Class: IRB::Pager

Inherits:
Object show all
Defined in:
lib/irb/pager.rb

Overview

The implementation of this class is borrowed from RDoc’s lib/rdoc/ri/driver.rb. Please do NOT use this class directly outside of IRB.

Defined Under Namespace

Classes: PageOverflowIO

Constant Summary collapse

PAGE_COMMANDS =
[ENV['RI_PAGER'], ENV['PAGER'], 'less', 'more'].compact.uniq

Class Method Summary collapse

Class Method Details

.page(retain_content: false) ⇒ Object

[View source]

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/irb/pager.rb', line 22

def page(retain_content: false)
  if should_page? && pager = setup_pager(retain_content: retain_content)
    begin
      pid = pager.pid
      yield pager
    ensure
      pager.close
    end
  else
    yield $stdout
  end
# When user presses Ctrl-C, IRB would raise `IRB::Abort`
# But since Pager is implemented by running paging commands like `less` in another process with `IO.popen`,
# the `IRB::Abort` exception only interrupts IRB's execution but doesn't affect the pager
# So to properly terminate the pager with Ctrl-C, we need to catch `IRB::Abort` and kill the pager process
rescue IRB::Abort
  begin
    begin
      Process.kill("TERM", pid) if pid
    rescue Errno::EINVAL
      # SIGTERM not supported (windows)
      Process.kill("KILL", pid)
    end
  rescue Errno::ESRCH
    # Pager process already terminated
  end
  nil
rescue Errno::EPIPE
end

.page_content(content, **options) ⇒ Object

[View source]

12
13
14
15
16
17
18
19
20
# File 'lib/irb/pager.rb', line 12

def page_content(content, **options)
  if content_exceeds_screen_height?(content)
    page(**options) do |io|
      io.puts content
    end
  else
    $stdout.puts content
  end
end

.page_with_preview(width, height, formatter_proc) {|out| ... } ⇒ Object

Yields:

  • (out)
[View source]

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/irb/pager.rb', line 56

def page_with_preview(width, height, formatter_proc)
  overflow_callback = ->(lines) do
    modified_output = formatter_proc.call(lines.join, true)
    content, = take_first_page(width, [height - 2, 0].max) {|o| o.write modified_output }
    content = content.chomp
    content = "#{content}\e[0m" if Color.colorable?
    $stdout.puts content
    $stdout.puts 'Preparing full inspection value...'
  end
  out = PageOverflowIO.new(width, height, overflow_callback, delay: 0.1)
  yield out
  content = formatter_proc.call(out.string, out.multipage?)
  if out.multipage?
    page(retain_content: true) do |io|
      io.puts content
    end
  else
    $stdout.puts content
  end
end

.should_page?Boolean

Returns:

  • (Boolean)
[View source]

52
53
54
# File 'lib/irb/pager.rb', line 52

def should_page?
  IRB.conf[:USE_PAGER] && STDIN.tty? && (ENV.key?("TERM") && ENV["TERM"] != "dumb")
end

.take_first_page(width, height) {|out| ... } ⇒ Object

Yields:

  • (out)
[View source]

77
78
79
80
81
82
83
84
# File 'lib/irb/pager.rb', line 77

def take_first_page(width, height)
  overflow_callback = proc do |lines|
    return lines.join, true
  end
  out = Pager::PageOverflowIO.new(width, height, overflow_callback)
  yield out
  [out.string, false]
end