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

ruby-changes:67381

From: aycabta <ko1@a...>
Date: Tue, 31 Aug 2021 15:19:42 +0900 (JST)
Subject: [ruby-changes:67381] 7fae57dbb4 (master): [ruby/reline] Use dynamic contents width

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

From 7fae57dbb45703c5d0695dc501cf7dca3c7c40a5 Mon Sep 17 00:00:00 2001
From: aycabta <aycabta@g...>
Date: Tue, 31 Aug 2021 06:40:25 +0900
Subject: [ruby/reline] Use dynamic contents width

https://github.com/ruby/reline/commit/f0e54f239b
---
 lib/reline/line_editor.rb | 91 ++++++++++++++++++++++++-----------------------
 1 file changed, 47 insertions(+), 44 deletions(-)

diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index e654d6b..f5c45d1 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -538,8 +538,8 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L538
   end
 
   class Dialog
-    attr_reader :name
-    attr_accessor :scroll_top, :column, :vertical_offset, :contents, :lines_backup
+    attr_reader :name, :contents, :contents_width
+    attr_accessor :scroll_top, :column, :vertical_offset, :lines_backup
 
     def initialize(name, proc_scope)
       @name = name
@@ -551,6 +551,11 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L551
       @proc_scope.set_cursor_pos(col, row)
     end
 
+    def contents=(contents)
+      @contents = contents
+      @contents_width = contents.map{ |line| Reline::Unicode.calculate_width(line, true) }.max if contents
+    end
+
     def call
       @proc_scope.set_dialog(self)
       @proc_scope.call
@@ -577,9 +582,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L582
     end
     dialog.set_cursor_pos(cursor_column, @first_line_started_from + @started_from)
     dialog_render_info = dialog.call
-    old_dialog_contents = dialog.contents
-    old_dialog_column = dialog.column
-    old_dialog_vertical_offset = dialog.vertical_offset
+    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
       pointer = dialog_render_info.pointer
@@ -612,7 +615,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L615
     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_WIDTH) - (@screen_size.last - 1)
+    diff = (dialog.column + dialog.contents_width) - (@screen_size.last - 1)
     if diff > 0
       dialog.column -= diff
     end
@@ -628,7 +631,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L631
       dialog.vertical_offset = dialog_render_info.pos.y + 1
     end
     Reline::IOGate.hide_cursor
-    reset_dialog(dialog, old_dialog_contents, old_dialog_column, old_dialog_vertical_offset)
+    reset_dialog(dialog, old_dialog)
     move_cursor_down(dialog.vertical_offset)
     Reline::IOGate.move_cursor_column(dialog.column)
     dialog.contents.each_with_index do |item, i|
@@ -641,7 +644,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L644
           bg_color = '46'
         end
       end
-      @output.write "\e[#{bg_color}m%-#{DIALOG_WIDTH}s\e[49m" % item.slice(0, DIALOG_WIDTH)
+      @output.write "\e[#{bg_color}m%-#{dialog.contents_width}s\e[49m" % item.slice(0, dialog.contents_width)
       Reline::IOGate.move_cursor_column(dialog.column)
       move_cursor_down(1) if i < (dialog.contents.size - 1)
     end
@@ -657,8 +660,8 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L660
     }
   end
 
-  private def reset_dialog(dialog, old_dialog_contents, old_dialog_column, old_dialog_vertical_offset)
-    return if dialog.lines_backup.nil? or old_dialog_contents.nil?
+  private def reset_dialog(dialog, old_dialog)
+    return if dialog.lines_backup.nil? or old_dialog.contents.nil?
     prompt, prompt_width, prompt_list = check_multiline_prompt(dialog.lines_backup[:lines], prompt)
     visual_lines = []
     visual_start = nil
@@ -674,76 +677,76 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L677
     old_y = dialog.lines_backup[:first_line_started_from] + dialog.lines_backup[:started_from]
     y = @first_line_started_from + @started_from
     y_diff = y - old_y
-    if (old_y + old_dialog_vertical_offset) < (y + dialog.vertical_offset)
+    if (old_y + old_dialog.vertical_offset) < (y + dialog.vertical_offset)
       # rerender top
-      move_cursor_down(old_dialog_vertical_offset - y_diff)
-      start = visual_start + old_dialog_vertical_offset
-      line_num = dialog.vertical_offset - old_dialog_vertical_offset
+      move_cursor_down(old_dialog.vertical_offset - y_diff)
+      start = visual_start + old_dialog.vertical_offset
+      line_num = dialog.vertical_offset - old_dialog.vertical_offset
       line_num.times do |i|
-        Reline::IOGate.move_cursor_column(old_dialog_column)
+        Reline::IOGate.move_cursor_column(old_dialog.column)
         if visual_lines[start + i].nil?
-          s = ' ' * DIALOG_WIDTH
+          s = ' ' * dialog.contents_width
         else
-          s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog_column, DIALOG_WIDTH)
+          s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, dialog.contents_width)
         end
-        @output.write "\e[39m\e[49m%-#{DIALOG_WIDTH}s\e[39m\e[49m" % s
+        @output.write "\e[39m\e[49m%-#{dialog.contents_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)
+      move_cursor_up(old_dialog.vertical_offset + line_num - 1 - y_diff)
     end
-    if (old_y + old_dialog_vertical_offset + old_dialog_contents.size) > (y + dialog.vertical_offset + dialog.contents.size)
+    if (old_y + old_dialog.vertical_offset + old_dialog.contents.size) > (y + dialog.vertical_offset + dialog.contents.size)
       # rerender bottom
       move_cursor_down(dialog.vertical_offset + dialog.contents.size - y_diff)
       start = visual_start + dialog.vertical_offset + dialog.contents.size
-      line_num = (old_dialog_vertical_offset + old_dialog_contents.size) - (dialog.vertical_offset + dialog.contents.size)
+      line_num = (old_dialog.vertical_offset + old_dialog.contents.size) - (dialog.vertical_offset + dialog.contents.size)
       line_num.times do |i|
-        Reline::IOGate.move_cursor_column(old_dialog_column)
+        Reline::IOGate.move_cursor_column(old_dialog.column)
         if visual_lines[start + i].nil?
-          s = ' ' * DIALOG_WIDTH
+          s = ' ' * dialog.contents_width
         else
-          s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog_column, DIALOG_WIDTH)
+          s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, dialog.contents_width)
         end
-        @output.write "\e[39m\e[49m%-#{DIALOG_WIDTH}s\e[39m\e[49m" % s
+        @output.write "\e[39m\e[49m%-#{dialog.contents_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)
     end
-    if old_dialog_column < dialog.column
+    if old_dialog.column < dialog.column
       # rerender left
-      move_cursor_down(old_dialog_vertical_offset - y_diff)
-      width = dialog.column - old_dialog_column
-      start = visual_start + old_dialog_vertical_offset
-      line_num = old_dialog_contents.size
+      move_cursor_down(old_dialog.vertical_offset - y_diff)
+      width = dialog.column - old_dialog.column
+      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)
+        Reline::IOGate.move_cursor_column(old_dialog.column)
         if visual_lines[start + i].nil?
           s = ' ' * width
         else
-          s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog_column, width)
+          s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column, width)
         end
         @output.write "\e[39m\e[49m%-#{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)
+      move_cursor_up(old_dialog.vertical_offset + line_num - 1 - y_diff)
     end
-    if (old_dialog_column + DIALOG_WIDTH) > (dialog.column + DIALOG_WIDTH)
+    if (old_dialog.column + old_dialog.contents_width) > (dialog.column + dialog.contents_width)
       # rerender right
-      move_cursor_down(old_dialog_vertical_offset + y_diff)
-      width = (old_dialog_column + DIALOG_WIDTH) - (dialog.column + DIALOG_WIDTH)
-      start = visual_start + old_dialog_vertical_offset
-      line_num = old_dialog_contents.size
+      move_cursor_down(old_dialog.vertical_offset + y_diff)
+      width = (old_dialog.column + old_dialog.contents_width) - (dialog.column + dialog.contents_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_WIDTH)
+        Reline::IOGate.move_cursor_column(old_dialog.column + dialog.contents_width)
         if visual_lines[start + i].nil?
           s = ' ' * width
         else
-          s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog_column + DIALOG_WIDTH, width)
+          s = Reline::Unicode.take_range(visual_lines[start + i], old_dialog.column + dialog.contents_width, width)
         end
-        Reline::IOGate.move_cursor_column(dialog.column + DIALOG_WIDTH)
+        Reline::IOGate.move_cursor_column(dialog.column + dialog.contents_width)
         @output.write "\e[39m\e[49m%-#{width}s\e[39m\e[49m" % s
       (... truncated)

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

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