Module: CommandKit::Pager

Includes:
Env, Env::Path, Stdio, Terminal
Defined in:
lib/command_kit/pager.rb

Overview

Allows opening a pager, such as less or more.

Examples

class CLI < CommandKit::Command

  include CommandKit::Pager

  def run
    pager do |io|
      io.puts "This goes into the pager screen"
    end
  end

end

Environment Variables

  • PAGER - The optional command to override the default pager (usually less -r or more -r).
  • PATH - The list of directories to search for the default pager program (either less or more).

Alternatives

Constant Summary collapse

PAGERS =

Common pager commands.

['less -r', 'more -r']

Constants included from Terminal

Terminal::DEFAULT_TERMINAL_HEIGHT, Terminal::DEFAULT_TERMINAL_WIDTH

Instance Attribute Summary

Attributes included from Env

#env

Attributes included from Env::Path

#path_dirs

Instance Method Summary collapse

Methods included from Terminal

#terminal, #terminal?, #terminal_height, #terminal_size, #terminal_width

Methods included from Stdio

#abort, #gets, #print, #printf, #putc, #puts, #readline, #readlines, #stderr, #stdin, #stdout

Methods included from Env::Path

#command_installed?, #find_command

Instance Method Details

#initialize(**kwargs) ⇒ Object

Note:

Respects the PAGER env variable, or attempts to find less or more by searching the PATH env variable.

Initializes the pager.



60
61
62
63
64
65
66
67
68
69
70
# File 'lib/command_kit/pager.rb', line 60

def initialize(**kwargs)
  super(**kwargs)

  @pager_command = env.fetch('PAGER') do
    PAGERS.find do |command|
      bin = command.split(' ',2).first

      command_installed?(bin)
    end
  end
end

#pager {|io| ... } ⇒ Object

Opens a pager pipe.

Examples:

pager do |io|
  io.puts "Hello world"
  # ...
end

Piping a command into the pager:

IO.peopn(["ping", ip]) do |ping|
  pager do |io|
    ping.each_line do |line|
      io.write line
    end
  end
end

Yields:

  • (io)

    The given block will be passed the IO pipe to the pager.

Yield Parameters:

  • The (IO)

    IO pipe to the pager.



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/command_kit/pager.rb', line 98

def pager
  if !stdout.tty? || @pager_command.nil?
    # fallback to stdout if the process does not have a terminal or we could
    # not find a suitable pager command.
    yield stdout
    return
  end

  io  = IO.popen(@pager_command,'w')
  pid = io.pid

  begin
    yield io
  rescue Errno::EPIPE
  ensure
    io.close

    begin
      Process.waitpid(pid)
    rescue Errno::EPIPE, Errno::ECHILD
    end
  end
end

#pipe_to_pager(command, *arguments) ⇒ Boolean

Note:

If multiple arguments are given, they will be shell-escaped and executed as a single command. If a single command is given, it will not be shell-escaped to allow executing compound shell commands.

Pipes a command into the pager.

Examples:

Pipe a single command into the pager:

run_in_pager 'find', '.', '-name', '*.md'

Pipe a compound command into the pager:

run_in_pager "wc -l /path/to/wordlists/*.txt | sort -n"

Since:

  • 0.2.0



178
179
180
181
182
183
184
185
186
187
188
# File 'lib/command_kit/pager.rb', line 178

def pipe_to_pager(command,*arguments)
  if @pager_command
    unless arguments.empty?
      command = Shellwords.shelljoin([command, *arguments])
    end

    system("#{command} | #{@pager_command}")
  else
    system(command.to_s,*arguments.map(&:to_s))
  end
end

Pages the data if it's longer the terminal's height, otherwise prints the data to stdout.

Examples:

print_or_page(data)

Print or pages the contents of a file:

print_or_page(File.read(file))


137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/command_kit/pager.rb', line 137

def print_or_page(data)
  line_count = case data
               when Array  then data.length
               else             data.to_s.each_line.count
               end

  if line_count > terminal_height
    pager { |io| io.puts(data) }
  else
    stdout.puts(data)
  end
end