Class: Toys::Utils::Pager

Inherits:
Object
  • Object
show all
Defined in:
lib/toys/utils/pager.rb

Overview

A class that invokes an external pager.

Examples:

Using a pager for regular output


Toys::Utils::Pager.start do |io|
  io.puts "A long string\n"
end

Piping output from a command


exec_service = Toys::Utils::Exec.new
Toys::Utils::Pager.start(exec_service: exec_service) do |io|
  exec_service.exec(["/bin/ls", "-alF"], out: io)
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(command: true, exec_service: nil, output: nil, fallback_io: nil, rescue_broken_pipes: true) ⇒ Pager

Creates a new pager.

Parameters:

  • command (String, Array<String>, boolean) (defaults to: true) —

    The command to use to invoke the pager. May be specified as a string to be passed to the shell, an array of strings representing a posix command, the value true to use the default (normally less -FIRX), or the value false to disable the pager and write directly to the output stream. Default is true.

  • exec_service (Toys::Utils::Exec) (defaults to: nil) —

    The service to use for executing commands, or nil (the default) to use a default.

  • output (IO, StringIO, nil) (defaults to: nil) —

    The stream to which the pager process writes its output, and the default fallback stream. If nil (the default), the pager process inherits the parent's standard output.

  • fallback_io (IO) (defaults to: nil) —

    An IO-like object to write to if the pager is disabled or could not be executed. Defaults to the output stream if one is given, otherwise $stdout.

  • rescue_broken_pipes (boolean) (defaults to: true) —

    If true (the default), broken pipes are silently rescued. This prevents the exception from propagating out if the pager is interrupted. Set this parameter to false to disable this behavior.



44
45
46
47
48
49
50
51
52
# File 'lib/toys/utils/pager.rb', line 44

def initialize(command: true, exec_service: nil, output: nil, fallback_io: nil,
               rescue_broken_pipes: true)
  @command = command == true ? Pager.default_command : command
  @command ||= nil
  @exec_service = exec_service || Pager.default_exec_service
  @output = output
  @fallback_io = fallback_io
  @rescue_broken_pipes = rescue_broken_pipes
end

Instance Attribute Details

#command ⇒ String, ...

The command for running the pager process. May be specified as a string to be passed to the shell, an array of strings representing a posix command, or nil to disable the pager and write directly to an output stream.

Returns:

  • (String, Array<String>, nil)


96
97
98
# File 'lib/toys/utils/pager.rb', line 96

def command
  @command
end

#fallback_io ⇒ IO

The IO stream used if the pager is disabled or could not be executed. If not set explicitly, this is the #output stream if one is set, otherwise $stdout.

Returns:

  • (IO)


113
114
115
# File 'lib/toys/utils/pager.rb', line 113

def fallback_io
  @fallback_io || @output || $stdout
end

#output ⇒ IO, ...

The stream to which the pager process writes its output, or nil if the pager process inherits the parent's standard output.

Returns:

  • (IO, StringIO, nil)


104
105
106
# File 'lib/toys/utils/pager.rb', line 104

def output
  @output
end

Class Method Details

.start(command: true, exec_service: nil, output: nil, fallback_io: nil, rescue_broken_pipes: true, &block) ⇒ Integer

A convenience method that creates a pager and runs it once by calling #start.

Examples:


Toys::Utils::Pager.start do |io|
  io.puts "A long string\n"
end

Parameters:

  • command (String, Array<String>, boolean) (defaults to: true) —

    The command to use to invoke the pager. May be specified as a string to be passed to the shell, an array of strings representing a posix command, the value true to use the default (normally less -FIRX), or the value false to disable the pager and write directly to the output stream. Default is true.

  • exec_service (Toys::Utils::Exec) (defaults to: nil) —

    The service to use for executing commands, or nil (the default) to use a default.

  • output (IO, StringIO, nil) (defaults to: nil) —

    The stream to which the pager process writes its output, and the default fallback stream. If nil (the default), the pager process inherits the parent's standard output.

  • fallback_io (IO) (defaults to: nil) —

    An IO-like object to write to if the pager is disabled or could not be executed. Defaults to the output stream if one is given, otherwise $stdout.

  • rescue_broken_pipes (boolean) (defaults to: true) —

    If true (the default), broken pipes are silently rescued. This prevents the exception from propagating out if the pager is interrupted. Set this parameter to false to disable this behavior.

Returns:

  • (Integer) —

    The exit code of the pager process.



156
157
158
159
160
161
162
163
164
165
# File 'lib/toys/utils/pager.rb', line 156

def start(command: true,
          exec_service: nil,
          output: nil,
          fallback_io: nil,
          rescue_broken_pipes: true,
          &block)
  pager = new(command: command, exec_service: exec_service, output: output,
              fallback_io: fallback_io, rescue_broken_pipes: rescue_broken_pipes)
  pager.start(&block)
end

Instance Method Details

#start {|io| ... } ⇒ Integer

Runs the pager. Takes a block and yields an IO-like object that passes text to the pager. Can be called multiple times on the same pager.

Examples:


pager = Toys::Utils::Pager.new
pager.start do |io|
  io.puts "A long string\n"
end

Yield Parameters:

  • io (IO) —

    An object that can be written to, to pass data to the pager.

Returns:

  • (Integer) —

    The exit code of the pager process.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/toys/utils/pager.rb', line 69

def start
  if @command
    exec_opts = { in: :controller }
    exec_opts[:out] = @output if @output
    result = @exec_service.exec(@command, **exec_opts) do |controller|
      yield controller.in if controller.pid
    rescue ::Errno::EPIPE => e
      if @rescue_broken_pipes
        return 1
      else
        raise e
      end
    end
    return result.exit_code unless result.failed?
  end
  yield fallback_io
  0
end