diff options
author | Takashi Kokubun <[email protected]> | 2021-03-20 23:15:51 -0700 |
---|---|---|
committer | git <[email protected]> | 2021-03-21 15:19:04 +0900 |
commit | d0b044a842ec03525ab839eb79864899ad81bed3 (patch) | |
tree | 0478ee62d54dacd4815fdcc3006fd1d3c55d00e1 /lib | |
parent | 21863470d965b8cc299b1f82417c70d5d26f8ab2 (diff) |
[ruby/irb] Fix column overflow on ls output
https://github.com/ruby/irb/commit/6115754623
Diffstat (limited to 'lib')
-rw-r--r-- | lib/irb/cmd/ls.rb | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/lib/irb/cmd/ls.rb b/lib/irb/cmd/ls.rb index c39937d4db..07e6fbc487 100644 --- a/lib/irb/cmd/ls.rb +++ b/lib/irb/cmd/ls.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require "reline" require_relative "nop" require_relative "../color" @@ -23,8 +24,11 @@ module IRB end class Output + MARGIN = " " + def initialize(grep: nil) @grep = grep + @line_width = screen_width end def dump(name, strs) @@ -32,14 +36,45 @@ module IRB strs = strs.sort return if strs.empty? + # Attempt a single line print "#{Color.colorize(name, [:BOLD, :BLUE])}: " - if strs.size > 7 - len = [strs.map(&:length).max, 16].min - puts; strs.each_slice(7) { |ss| puts " #{ss.map { |s| "%-#{len}s" % s }.join(" ")}" } - else - puts strs.join(" ") + if fits_on_line?(strs, cols: strs.size, offset: "#{name}: ".length) + puts strs.join(MARGIN) + return + end + puts + + # Dump with the largest # of columns that fits on a line + cols = strs.size + until fits_on_line?(strs, cols: cols, offset: MARGIN.length) || cols == 1 + cols -= 1 + 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 + end + end + + private + + def fits_on_line?(strs, cols:, offset: 0) + width = col_widths(strs, cols: cols).sum + MARGIN.length * (cols - 1) + width <= @line_width - offset + end + + def col_widths(strs, cols:) + cols.times.map do |col| + (col...strs.size).step(cols.size - 1).map do |i| + strs[i].length + end.max end end + + def screen_width + Reline.get_screen_size.last + rescue Errno::EINVAL # in `winsize': Invalid argument - <STDIN> + 79 + end end private_constant :Output end |