class IRB::Pager
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
.
Constants
- PAGE_COMMANDS
Public Class Methods
page() { |pager| ... }
click to toggle source
# File irb/pager.rb, line 20 def page if STDIN.tty? && pager = setup_pager 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 Process.kill("TERM", pid) if pid nil rescue Errno::EPIPE end
page_content(content)
click to toggle source
# File irb/pager.rb, line 10 def page_content(content) if content_exceeds_screen_height?(content) page do |io| io.puts content end else $stdout.puts content end end
Private Class Methods
content_exceeds_screen_height?(content)
click to toggle source
# File irb/pager.rb, line 43 def content_exceeds_screen_height?(content) screen_height, screen_width = begin Reline.get_screen_size rescue Errno::EINVAL [24, 80] end pageable_height = screen_height - 3 # leave some space for previous and the current prompt # If the content has more lines than the pageable height content.lines.count > pageable_height || # Or if the content is a few long lines pageable_height * screen_width < Reline::Unicode.calculate_width(content, true) end
setup_pager()
click to toggle source
# File irb/pager.rb, line 58 def setup_pager require 'shellwords' PAGE_COMMANDS.each do |pager| pager = Shellwords.split(pager) next if pager.empty? if pager.first == 'less' || pager.first == 'more' pager << '-R' unless pager.include?('-R') end begin io = IO.popen(pager, 'w') rescue next end if $? && $?.pid == io.pid && $?.exited? # pager didn't work next end return io end nil end