[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]