зеркало из https://github.com/github/ruby.git
[ruby/irb] Page `ls`'s output (https://github.com/ruby/irb/pull/657)
* Page ls command's output * Use Pager.page_content in show_cmds too https://github.com/ruby/irb/commit/82d1687302
This commit is contained in:
Родитель
26aef1c736
Коммит
283b2fdab4
|
@ -1,7 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "reline"
|
||||
require "stringio"
|
||||
require_relative "nop"
|
||||
require_relative "../pager"
|
||||
require_relative "../color"
|
||||
|
||||
module IRB
|
||||
|
@ -33,7 +35,7 @@ module IRB
|
|||
o.dump("instance variables", obj.instance_variables)
|
||||
o.dump("class variables", klass.class_variables)
|
||||
o.dump("locals", locals)
|
||||
nil
|
||||
o.print_result
|
||||
end
|
||||
|
||||
def dump_methods(o, klass, obj)
|
||||
|
@ -77,6 +79,11 @@ module IRB
|
|||
def initialize(grep: nil)
|
||||
@grep = grep
|
||||
@line_width = screen_width - MARGIN.length # right padding
|
||||
@io = StringIO.new
|
||||
end
|
||||
|
||||
def print_result
|
||||
Pager.page_content(@io.string)
|
||||
end
|
||||
|
||||
def dump(name, strs)
|
||||
|
@ -85,12 +92,12 @@ module IRB
|
|||
return if strs.empty?
|
||||
|
||||
# Attempt a single line
|
||||
print "#{Color.colorize(name, [:BOLD, :BLUE])}: "
|
||||
@io.print "#{Color.colorize(name, [:BOLD, :BLUE])}: "
|
||||
if fits_on_line?(strs, cols: strs.size, offset: "#{name}: ".length)
|
||||
puts strs.join(MARGIN)
|
||||
@io.puts strs.join(MARGIN)
|
||||
return
|
||||
end
|
||||
puts
|
||||
@io.puts
|
||||
|
||||
# Dump with the largest # of columns that fits on a line
|
||||
cols = strs.size
|
||||
|
@ -99,7 +106,7 @@ module IRB
|
|||
end
|
||||
widths = col_widths(strs, cols: cols)
|
||||
strs.each_slice(cols) do |ss|
|
||||
puts ss.map.with_index { |s, i| "#{MARGIN}%-#{widths[i]}s" % s }.join
|
||||
@io.puts ss.map.with_index { |s, i| "#{MARGIN}%-#{widths[i]}s" % s }.join
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -29,9 +29,7 @@ module IRB
|
|||
output.puts
|
||||
end
|
||||
|
||||
Pager.page do |io|
|
||||
io.puts output.string
|
||||
end
|
||||
Pager.page_content(output.string)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,6 +7,16 @@ module IRB
|
|||
PAGE_COMMANDS = [ENV['RI_PAGER'], ENV['PAGER'], 'less', 'more'].compact.uniq
|
||||
|
||||
class << self
|
||||
def page_content(content)
|
||||
if content_exceeds_screen_height?(content)
|
||||
page do |io|
|
||||
io.puts content
|
||||
end
|
||||
else
|
||||
$stdout.puts content
|
||||
end
|
||||
end
|
||||
|
||||
def page
|
||||
if STDIN.tty? && pager = setup_pager
|
||||
begin
|
||||
|
@ -30,6 +40,21 @@ module IRB
|
|||
|
||||
private
|
||||
|
||||
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
|
||||
|
||||
def setup_pager
|
||||
require 'shellwords'
|
||||
|
||||
|
|
|
@ -710,6 +710,16 @@ module TestIRB
|
|||
end
|
||||
|
||||
class LsTest < CommandTestCase
|
||||
def setup
|
||||
STDIN.singleton_class.define_method :tty? do
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def teardown
|
||||
STDIN.singleton_class.remove_method :tty?
|
||||
end
|
||||
|
||||
def test_ls
|
||||
out, err = execute_lines(
|
||||
"class P\n",
|
||||
|
|
|
@ -270,6 +270,54 @@ class IRB::RenderingTest < Yamatanooroti::TestCase
|
|||
assert_match(/foobar/, screen)
|
||||
end
|
||||
|
||||
def test_pager_page_content_pages_output_when_it_does_not_fit_in_the_screen_because_of_total_length
|
||||
write_irbrc <<~'LINES'
|
||||
puts 'start IRB'
|
||||
require "irb/pager"
|
||||
LINES
|
||||
start_terminal(10, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
|
||||
write("IRB::Pager.page_content('a' * (80 * 8))\n")
|
||||
write("'foo' + 'bar'\n") # eval something to make sure IRB resumes
|
||||
close
|
||||
|
||||
screen = result.join("\n").sub(/\n*\z/, "\n")
|
||||
assert_match(/a{80}/, screen)
|
||||
# because pager is invoked, foobar will not be evaluated
|
||||
assert_not_match(/foobar/, screen)
|
||||
end
|
||||
|
||||
def test_pager_page_content_pages_output_when_it_does_not_fit_in_the_screen_because_of_screen_height
|
||||
write_irbrc <<~'LINES'
|
||||
puts 'start IRB'
|
||||
require "irb/pager"
|
||||
LINES
|
||||
start_terminal(10, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
|
||||
write("IRB::Pager.page_content('a\n' * 8)\n")
|
||||
write("'foo' + 'bar'\n") # eval something to make sure IRB resumes
|
||||
close
|
||||
|
||||
screen = result.join("\n").sub(/\n*\z/, "\n")
|
||||
assert_match(/(a\n){8}/, screen)
|
||||
# because pager is invoked, foobar will not be evaluated
|
||||
assert_not_match(/foobar/, screen)
|
||||
end
|
||||
|
||||
def test_pager_page_content_doesnt_page_output_when_it_fits_in_the_screen
|
||||
write_irbrc <<~'LINES'
|
||||
puts 'start IRB'
|
||||
require "irb/pager"
|
||||
LINES
|
||||
start_terminal(10, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
|
||||
write("IRB::Pager.page_content('a' * (80 * 7))\n")
|
||||
write("'foo' + 'bar'\n") # eval something to make sure IRB resumes
|
||||
close
|
||||
|
||||
screen = result.join("\n").sub(/\n*\z/, "\n")
|
||||
assert_match(/a{80}/, screen)
|
||||
# because pager is not invoked, foobar will be evaluated
|
||||
assert_match(/foobar/, screen)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def write_irbrc(content)
|
||||
|
|
Загрузка…
Ссылка в новой задаче