類別 IRB::Pager

此類別的實作取自 RDoc 的 lib/rdoc/ri/driver.rb。請勿在 IRB 外部直接使用此類別。

常數

PAGE_COMMANDS

公開類別方法

page(retain_content: false) { |pager| ... } 按一下以切換來源
# File lib/irb/pager.rb, line 20
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
  Process.kill("TERM", pid) if pid
  nil
rescue Errno::EPIPE
end
page_content(content, **options) 按一下以切換來源
# File lib/irb/pager.rb, line 10
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

私人類別方法

content_exceeds_screen_height?(content) 按一下以切換來源
# File lib/irb/pager.rb, line 47
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(retain_content:) 按一下以切換來源
# File lib/irb/pager.rb, line 62
def setup_pager(retain_content:)
  require 'shellwords'

  PAGE_COMMANDS.each do |pager_cmd|
    cmd = Shellwords.split(pager_cmd)
    next if cmd.empty?

    if cmd.first == 'less'
      cmd << '-R' unless cmd.include?('-R')
      cmd << '-X' if retain_content && !cmd.include?('-X')
    end

    begin
      io = IO.popen(cmd, 'w')
    rescue
      next
    end

    if $? && $?.pid == io.pid && $?.exited? # pager didn't work
      next
    end

    return io
  end

  nil
end
should_page?() 按一下以切換來源
# File lib/irb/pager.rb, line 43
def should_page?
  IRB.conf[:USE_PAGER] && STDIN.tty? && (ENV.key?("TERM") && ENV["TERM"] != "dumb")
end