ruby-changes:65609
From: Takashi <ko1@a...>
Date: Sun, 21 Mar 2021 15:19:13 +0900 (JST)
Subject: [ruby-changes:65609] d0b044a842 (master): [ruby/irb] Fix column overflow on ls output
https://git.ruby-lang.org/ruby.git/commit/?id=d0b044a842 From d0b044a842ec03525ab839eb79864899ad81bed3 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun <takashikkbn@g...> Date: Sat, 20 Mar 2021 23:15:51 -0700 Subject: [ruby/irb] Fix column overflow on ls output https://github.com/ruby/irb/commit/6115754623 --- lib/irb/cmd/ls.rb | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/lib/irb/cmd/ls.rb b/lib/irb/cmd/ls.rb index c39937d..07e6fbc 100644 --- a/lib/irb/cmd/ls.rb +++ b/lib/irb/cmd/ls.rb @@ -1,5 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/lib/irb/cmd/ls.rb#L1 # frozen_string_literal: true +require "reline" require_relative "nop" require_relative "../color" @@ -23,8 +24,11 @@ module IRB https://github.com/ruby/ruby/blob/trunk/lib/irb/cmd/ls.rb#L24 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 https://github.com/ruby/ruby/blob/trunk/lib/irb/cmd/ls.rb#L36 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 -- cgit v1.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/