Class: TTY::Pager::SystemPager

Inherits:
Abstract
  • Object
show all
Defined in:
lib/tty/pager/system.rb

Overview

A system pager is used on systems where native pagination exists

Defined Under Namespace

Classes: PagerIO

Constant Summary

Constants inherited from Abstract

Abstract::UndefinedMethodError

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Abstract

#enabled?, page, #page, #try_write

Constructor Details

#initialize(command: nil, **options) ⇒ SystemPager

Create a system pager

Parameters:

  • :command (String)

    the command to use for paging



120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/tty/pager/system.rb', line 120

def initialize(command: nil, **options)
  super(**options)
  @pager_io = nil
  @pager_command = nil
  pager_command(*Array(command))

  if pager_command.nil?
    raise TTY::Pager::Error,
          "#{self.class.name} cannot be used on your system due to " \
          "lack of appropriate pager executable. Install `less` like " \
          "pager or try using `BasicPager` instead."
  end
end

Class Method Details

.command_exist?(command) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if command exists

Examples:

command_exist?("less") # => true

Parameters:

  • command (String)

    the command to check

Returns:

  • (Boolean)


26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/tty/pager/system.rb', line 26

def self.command_exist?(command)
  exts = ENV.fetch("PATHEXT", "").split(::File::PATH_SEPARATOR)
  if Pathname.new(command).absolute?
    ::File.exist?(command) ||
      exts.any? { |ext| ::File.exist?("#{command}#{ext}")}
  else
    ENV.fetch("PATH", "").split(::File::PATH_SEPARATOR).any? do |dir|
      file = ::File.join(dir, command)
      ::File.exist?(file) ||
        exts.any? { |ext| ::File.exist?("#{file}#{ext}") }
    end
  end
end

.exec_available?(*commands) ⇒ Boolean

Check if command is available

Examples:

Basic usage

available?  # => true

Usage with command

available?("less") # => true

Returns:

  • (Boolean)


110
111
112
# File 'lib/tty/pager/system.rb', line 110

def self.exec_available?(*commands)
  !find_executable(*commands).nil?
end

.executablesArray[String]

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

List possible executables for output paging

The UNIX systems often come with “pg” and “more” but no “less” utility. The Linux usually provides “less” and “more” pager, but often no “pg”. MacOS comes with “less” and “more” pager and no “pg”. Windows provides “more”. The “more” pager is the oldest utility and thus most compatible with many systems.

Returns:

  • (Array[String])


65
66
67
68
# File 'lib/tty/pager/system.rb', line 65

def self.executables
  [ENV["GIT_PAGER"], ENV["PAGER"], git_pager,
   "less -r", "more -r", "most", "pg", "cat", "pager"].compact
end

.find_executable(*commands) ⇒ String?

Find first available termainal pager program executable

Examples:

Basic usage

find_executable # => "less"

Usage with commands

find_executable("less", "cat")  # => "less"

Parameters:

  • commands (Array[String])

Returns:

  • (String, nil)

    the found executable or nil when not found



92
93
94
95
96
97
# File 'lib/tty/pager/system.rb', line 92

def self.find_executable(*commands)
  execs = commands.empty? ? executables : commands
  execs
    .compact.map(&:strip).reject(&:empty?).uniq
    .find { |cmd| command_exist?(cmd.split.first) }
end

.run_command(*args) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Run pager command silently with no input and capture output

Returns:

  • (Boolean)

    true if command runs successfully, false otherwise



46
47
48
49
50
51
# File 'lib/tty/pager/system.rb', line 46

def self.run_command(*args)
  _, err, status = Open3.capture3(*args)
  err.empty? && status.success?
rescue Errno::ENOENT
  false
end

Instance Method Details

#closeBoolean

Stop the pager, wait for the process to finish. If no pager has been started, returns true.

Returns:

  • (Boolean)

    the exit status of the child process



173
174
175
176
177
178
179
# File 'lib/tty/pager/system.rb', line 173

def close
  return true unless @pager_io

  success = @pager_io.close
  @pager_io = nil
  success
end

#puts(text) ⇒ SystemPager

Send a line of text, ending in a newline, to the pager process. Starts a new process if it hasn’t been started yet.

Returns:

Raises:



160
161
162
163
164
# File 'lib/tty/pager/system.rb', line 160

def puts(text)
  @pager_io ||= spawn_pager
  @pager_io.puts(text)
  self
end

#write(*args) ⇒ Object Also known as: <<

Send text to the pager process. Starts a new process if it hasn’t been started yet.

Parameters:

  • *args (Array<String>)

    strings to send to the pager

Raises:



144
145
146
147
148
# File 'lib/tty/pager/system.rb', line 144

def write(*args)
  @pager_io ||= spawn_pager
  @pager_io.write(*args)
  self
end