class TTY::Pager::SystemPager
A system pager is used on systems where native pagination exists
@api public
Public Class Methods
Check if command exists
@example
command_exist?("less") # => true
@param [String] command
the command to check
@return [Boolean]
@api private
# 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
Check if command is available
@example Basic usage
available? # => true
@example Usage with command
available?("less") # => true
@return [Boolean]
@api public
# File lib/tty/pager/system.rb, line 110 def self.exec_available?(*commands) !find_executable(*commands).nil? end
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.
@return [Array]
@api private
# 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 first available termainal pager program executable
@example Basic usage
find_executable # => "less"
@example Usage with commands
find_executable("less", "cat") # => "less"
@param [Array] commands
@return [String, nil]
the found executable or nil when not found
@api public
# 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
Create a system pager
@param [String] :command
the command to use for paging
@api public
TTY::Pager::Abstract::new
# 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
Run pager command silently with no input and capture output
@return [Boolean]
true if command runs successfully, false otherwise
@api private
# 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
Private Class Methods
Finds git pager configuration
@api private
# File lib/tty/pager/system.rb, line 73 def self.git_pager command_exist?("git") ? `git config --get-all core.pager` : nil end
Public Instance Methods
Stop the pager, wait for the process to finish. If no pager has been started, returns true.
@return [Boolean]
the exit status of the child process
@api public
# File lib/tty/pager/system.rb, line 173 def close return true unless @pager_io success = @pager_io.close @pager_io = nil success end
Send a line of text, ending in a newline, to the pager process. Starts a new process if it hasn't been started yet.
@raise [PagerClosed]
if the pager was closed
@return [SystemPager]
@api public
# File lib/tty/pager/system.rb, line 160 def puts(text) @pager_io ||= spawn_pager @pager_io.puts(text) self end
Send text to the pager process. Starts a new process if it hasn't been started yet.
@param [Array<String>] *args
strings to send to the pager
@raise [PagerClosed]
strings to send to the pager
@api public
# File lib/tty/pager/system.rb, line 144 def write(*args) @pager_io ||= spawn_pager @pager_io.write(*args) self end
Private Instance Methods
The pager command to run
@return [String]
the name of executable to run
@api private
# File lib/tty/pager/system.rb, line 189 def pager_command(*commands) if @pager_command && commands.empty? @pager_command else @pager_command = self.class.find_executable(*commands) end end
Spawn the pager process
@return [PagerIO]
A wrapper for the external pager
@api private
# File lib/tty/pager/system.rb, line 203 def spawn_pager # In case there's a previous pager running: close command = pager_command status = self.class.run_command(command) # Issue running command, e.g. unsupported flag, fallback to just command unless status command = pager_command.split.first end PagerIO.new(command) end