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

ruby-changes:67382

From: aycabta <ko1@a...>
Date: Tue, 31 Aug 2021 15:19:43 +0900 (JST)
Subject: [ruby-changes:67382] c8a07a1231 (master): [ruby/reline] Fix Reline::Unicode.take_range as it was not fully functional

https://git.ruby-lang.org/ruby.git/commit/?id=c8a07a1231

From c8a07a1231361f41963960d5acb129808f6d1c98 Mon Sep 17 00:00:00 2001
From: aycabta <aycabta@g...>
Date: Tue, 31 Aug 2021 15:09:04 +0900
Subject: [ruby/reline] Fix Reline::Unicode.take_range as it was not fully
 functional

https://github.com/ruby/reline/commit/5da6a8d851
---
 lib/reline.rb             |  2 +-
 lib/reline/line_editor.rb | 42 +++++++++++++++++++++++++-----------------
 lib/reline/unicode.rb     | 11 ++++++-----
 3 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/lib/reline.rb b/lib/reline.rb
index cf668c7..18ccce2 100644
--- a/lib/reline.rb
+++ b/lib/reline.rb
@@ -18,7 +18,7 @@ module Reline https://github.com/ruby/ruby/blob/trunk/lib/reline.rb#L18
 
   Key = Struct.new('Key', :char, :combined_char, :with_meta)
   CursorPos = Struct.new(:x, :y)
-  DialogRenderInfo = Struct.new(:pos, :contents, :pointer, :bg_color, :height, keyword_init: true)
+  DialogRenderInfo = Struct.new(:pos, :contents, :pointer, :bg_color, :width, :height, keyword_init: true)
 
   class Core
     ATTR_READER_NAMES = %i(
diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index f5c45d1..a42d9ae 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -538,12 +538,13 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L538
   end
 
   class Dialog
-    attr_reader :name, :contents, :contents_width
+    attr_reader :name, :contents, :width
     attr_accessor :scroll_top, :column, :vertical_offset, :lines_backup
 
     def initialize(name, proc_scope)
       @name = name
       @proc_scope = proc_scope
+      @width = nil
       @scroll_top = 0
     end
 
@@ -551,9 +552,15 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L552
       @proc_scope.set_cursor_pos(col, row)
     end
 
+    def width=(v)
+      @width = v
+    end
+
     def contents=(contents)
       @contents = contents
-      @contents_width = contents.map{ |line| Reline::Unicode.calculate_width(line, true) }.max if contents
+      if contents and @width.nil?
+        @width = contents.map{ |line| Reline::Unicode.calculate_width(line, true) }.max
+      end
     end
 
     def call
@@ -582,6 +589,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L589
     end
     dialog.set_cursor_pos(cursor_column, @first_line_started_from + @started_from)
     dialog_render_info = dialog.call
+    dialog.width = dialog_render_info.width if dialog_render_info.width
     old_dialog = dialog.clone
     if dialog_render_info and dialog_render_info.contents and not dialog_render_info.contents.empty?
       height = dialog_render_info.height || DIALOG_HEIGHT
@@ -615,7 +623,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L623
     upper_space = @first_line_started_from - @started_from
     lower_space = @highest_in_all - @first_line_started_from - @started_from - 1
     dialog.column = dialog_render_info.pos.x
-    diff = (dialog.column + dialog.contents_width) - (@screen_size.last - 1)
+    diff = (dialog.column + dialog.width) - (@screen_size.last - 1)
     if diff > 0
       dialog.column -= diff
     end
@@ -644,7 +652,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L652
           bg_color = '46'
         end
       end
-      @output.write "\e[#{bg_color}m%-#{dialog.contents_width}s\e[49m" % item.slice(0, dialog.contents_width)
+      @output.write "\e[#{bg_color}m%-#{dialog.width}s\e[49m" % item.slice(0, dialog.width)
       Reline::IOGate.move_cursor_column(dialog.column)
       move_cursor_down(1) if i < (dialog.contents.size - 1)
     end
@@ -685,11 +693,11 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L693
       line_num.times do |i|
         Reline::IOGate.move_cursor_column(old_dialog.column)
         if visual_lines[start + i].nil?
-          s = ' ' * dialog.contents_width
+          s = ' ' * dialog.width
         else
-          s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, dialog.contents_width)
+          s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, dialog.width)
         end
-        @output.write "\e[39m\e[49m%-#{dialog.contents_width}s\e[39m\e[49m" % s
+        @output.write "\e[39m\e[49m%-#{dialog.width}s\e[39m\e[49m" % s
         move_cursor_down(1) if i < (line_num - 1)
       end
       move_cursor_up(old_dialog.vertical_offset + line_num - 1 - y_diff)
@@ -702,11 +710,11 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L710
       line_num.times do |i|
         Reline::IOGate.move_cursor_column(old_dialog.column)
         if visual_lines[start + i].nil?
-          s = ' ' * dialog.contents_width
+          s = ' ' * dialog.width
         else
-          s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, dialog.contents_width)
+          s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, dialog.width)
         end
-        @output.write "\e[39m\e[49m%-#{dialog.contents_width}s\e[39m\e[49m" % s
+        @output.write "\e[39m\e[49m%-#{dialog.width}s\e[39m\e[49m" % s
         move_cursor_down(1) if i < (line_num - 1)
       end
       move_cursor_up(dialog.vertical_offset + dialog.contents.size + line_num - 1 - y_diff)
@@ -729,20 +737,20 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L737
       end
       move_cursor_up(old_dialog.vertical_offset + line_num - 1 - y_diff)
     end
-    if (old_dialog.column + old_dialog.contents_width) > (dialog.column + dialog.contents_width)
+    if (old_dialog.column + old_dialog.width) > (dialog.column + dialog.width)
       # rerender right
       move_cursor_down(old_dialog.vertical_offset + y_diff)
-      width = (old_dialog.column + old_dialog.contents_width) - (dialog.column + dialog.contents_width)
+      width = (old_dialog.column + old_dialog.width) - (dialog.column + dialog.width)
       start = visual_start + old_dialog.vertical_offset
       line_num = old_dialog.contents.size
       line_num.times do |i|
-        Reline::IOGate.move_cursor_column(old_dialog.column + dialog.contents_width)
+        Reline::IOGate.move_cursor_column(old_dialog.column + dialog.width)
         if visual_lines[start + i].nil?
           s = ' ' * width
         else
-          s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column + dialog.contents_width, width)
+          s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column + dialog.width, width)
         end
-        Reline::IOGate.move_cursor_column(dialog.column + dialog.contents_width)
+        Reline::IOGate.move_cursor_column(dialog.column + dialog.width)
         @output.write "\e[39m\e[49m%-#{width}s\e[39m\e[49m" % s
         move_cursor_down(1) if i < (line_num - 1)
       end
@@ -780,10 +788,10 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L788
     dialog_vertical_size.times do |i|
       if i < visual_lines_under_dialog.size
         Reline::IOGate.move_cursor_column(0)
-        @output.write "\e[39m\e[49m%-#{dialog.contents_width}s\e[39m\e[49m" % visual_lines_under_dialog[i]
+        @output.write "\e[39m\e[49m%-#{dialog.width}s\e[39m\e[49m" % visual_lines_under_dialog[i]
       else
         Reline::IOGate.move_cursor_column(dialog.column)
-        @output.write "\e[39m\e[49m#{' ' * dialog.contents_width}\e[39m\e[49m"
+        @output.write "\e[39m\e[49m#{' ' * dialog.width}\e[39m\e[49m"
       end
       Reline::IOGate.erase_after_cursor
       move_cursor_down(1) if i < (dialog_vertical_size - 1)
diff --git a/lib/reline/unicode.rb b/lib/reline/unicode.rb
index 3bb08fa..d111a84 100644
--- a/lib/reline/unicode.rb
+++ b/lib/reline/unicode.rb
@@ -186,9 +186,9 @@ class Reline::Unicode https://github.com/ruby/ruby/blob/trunk/lib/reline/unicode.rb#L186
   end
 
   # Take a chunk of a String with escape sequences.
-  def self.take_range(str, col, length, encoding = str.encoding)
+  def self.take_range(str, start_col, max_width, encoding = str.encoding)
     chunk = String.new(encoding: encoding)
-    width = 0
+    total_width = 0
     rest = str.encode(Encoding::UTF_8)
     in_zero_width = false
     rest.scan(WIDTH_SCANNER) do |gc|
@@ -206,9 +206,10 @@ class Reline::Unicode https://github.com/ruby/ruby/blob/trunk/lib/reline/unicode.rb#L206
         if in_zero_width
           chunk << gc
         else
-          width = get_mbchar_width(gc)
-          break if (width + length) <= col
-          chunk << gc if col <= width
+          mbchar_width = get_mbchar_width(gc)
+          total_width += mbchar_width
+          break if (start_col + max_width) < total_width
+          chunk << gc if start_col < total_width
         end
       end
     end
-- 
cgit v1.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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