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

ruby-changes:63925

From: aycabta <ko1@a...>
Date: Sat, 5 Dec 2020 03:09:17 +0900 (JST)
Subject: [ruby-changes:63925] 266ffdde8e (master): [ruby/reline] Continuous insertion buffering

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

From 266ffdde8eeb9b6626030653a927f033d7464cdf Mon Sep 17 00:00:00 2001
From: aycabta <aycabta@g...>
Date: Sat, 31 Oct 2020 16:45:15 +0900
Subject: [ruby/reline] Continuous insertion buffering

The rendering time in IRB has been reduced as follows:

  start = Time.now

  [{"_id"=>"5f9072a4589a06d2d74b6028",
    "index"=>0,
    "guid"=>"6b3051e2-dbc7-4537-bdb9-6cd7bb5358a7",
    "isActive"=>true,
    "balance"=>"$1,442.84",
    "picture"=>"http://placehold.it/32x32",
    "age"=>34,
    "eyeColor"=>"blue",
    "name"=>{"first"=>"Ward", "last"=>"Levy"},
    "company"=>"HYPLEX",
    "email"=>"ward.levy@h...",
    "phone"=>"+1 (867) 568-3319",
    "address"=>"867 Cobek Court, Clara, Maryland, 3254",
    "about"=>
     "Exercitation eu ex aliqua sit. Pariatur aliquip incididunt sint id non consectetur ullamco Lorem ea mollit duis amet sint labore. Commodo laborum labore commodo officia in cillum adipisicing esse excepteur cupidatat adipisicing ut. Non esse incididunt voluptate aliquip cillum eu aute duis laboris sit et. Amet enim quis tempor occaecat excepteur exercitation excepteur deserunt amet cillum adipisicing.",
    "registered"=>"Monday, May 25, 2015 6:51 AM",
    "latitude"=>"16.001127",
    "longitude"=>"-72.377848",
    "tags"=>["dolore", "nostrud", "occaecat", "cillum", "nisi"],
    "range"=>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
    "friends"=>
     [{"id"=>0, "name"=>"Alison Bryant"},
      {"id"=>1, "name"=>"Ester Espinoza"},
      {"id"=>2, "name"=>"Sullivan Kane"}],
    "greeting"=>"Hello, Ward! You have 7 unread messages.",
    "favoriteFruit"=>"apple"}]

  puts "Duration: #{Time.now - start} seconds"

2.17sec -> 0.92sec

  start = Time.now

  "Exercitation eu ex aliqua sit. Pariatur aliquip incididunt sint id non consectetur ullamco Lorem ea mollit duis amet sint labore. Commodo laborum labore commodo officia in cillum adipisicing esse excepteur cupidatat adipisicing ut. Non esse incididunt voluptate aliquip cillum eu aute duis laboris sit et. Amet enim quis tempor occaecat excepteur exercitation excepteur deserunt amet cillum adipisicing."

  puts "Duration: #{Time.now - start} seconds"

1.57sec -> 0.22sec

  start = Time.now

  def each_top_level_statement
    initialize_input
    catch(:TERM_INPUT) do
      loop do
        begin
          prompt
          unless l = lex
            throw :TERM_INPUT if @line == ''
          else
            @line_no += l.count("\n")
            next if l == "\n"
            @line.concat l
            if @code_block_open or @ltype or @continue or @indent > 0
              next
            end
          end
          if @line != "\n"
            @line.force_encoding(@io.encoding)
            yield @line, @exp_line_no
          end
          break if @io.eof?
          @line = ''
          @exp_line_no = @line_no

          @indent = 0
        rescue TerminateLineInput
          initialize_input
          prompt
        end
      end
    end
  end

  puts "Duration: #{Time.now - start} seconds"

0.88sec -> 0.77sec

https://github.com/ruby/reline/commit/7d87ac5a12

diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index 5558a1b..325475f 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -187,6 +187,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L187
     @searching_prompt = nil
     @first_char = true
     @eof = false
+    @continuous_insertion_buffer = String.new(encoding: @encoding)
     reset_line
   end
 
@@ -728,6 +729,18 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L729
     method_obj and method_obj.parameters.length != 1
   end
 
+  def wrap_method_call(method_symbol, method_obj, key)
+    if @config.editing_mode_is?(:emacs, :vi_insert) and @waiting_proc.nil? and @waiting_operator_proc.nil?
+      not_insertion = method_symbol != :ed_insert
+      process_insert(force: not_insertion)
+    end
+    if @vi_arg
+      method_obj.(key, arg: @vi_arg)
+    else
+      method_obj.(key)
+    end
+  end
+
   private def process_key(key, method_symbol)
     if method_symbol and respond_to?(method_symbol, true)
       method_obj = method(method_symbol)
@@ -737,10 +750,10 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L750
     if method_symbol and key.is_a?(Symbol)
       if @vi_arg and argumentable?(method_obj)
         run_for_operators(key, method_symbol) do
-          method_obj.(key, arg: @vi_arg)
+          wrap_method_call(method_symbol, method_obj, key)
         end
       else
-        method_obj&.(key)
+        wrap_method_call(method_symbol, method_obj, key) if method_obj
       end
       @kill_ring.process
       @vi_arg = nil
@@ -750,12 +763,12 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L763
       else
         if argumentable?(method_obj)
           run_for_operators(key, method_symbol) do
-            method_obj.(key, arg: @vi_arg)
+            wrap_method_call(method_symbol, method_obj, key)
           end
         elsif @waiting_proc
           @waiting_proc.(key)
         elsif method_obj
-          method_obj.(key)
+          wrap_method_call(method_symbol, method_obj, key)
         else
           ed_insert(key)
         end
@@ -767,10 +780,10 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L780
       @kill_ring.process
     elsif method_obj
       if method_symbol == :ed_argument_digit
-        method_obj.(key)
+        wrap_method_call(method_symbol, method_obj, key)
       else
         run_for_operators(key, method_symbol) do
-          method_obj.(key)
+          wrap_method_call(method_symbol, method_obj, key)
         end
       end
       @kill_ring.process
@@ -832,6 +845,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L845
         result = call_completion_proc
         if result.is_a?(Array)
           completion_occurs = true
+          process_insert
           complete(result)
         end
       end
@@ -840,6 +854,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L854
         result = call_completion_proc
         if result.is_a?(Array)
           completion_occurs = true
+          process_insert
           move_completed_list(result, "\C-p".ord == key.char ? :up : :down)
         end
       end
@@ -1092,38 +1107,55 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L1107
 
   private def ed_unassigned(key) end # do nothing
 
+  private def process_insert(force: false)
+    return if @continuous_insertion_buffer.empty? or (Reline::IOGate.in_pasting? and not force)
+    width = Reline::Unicode.calculate_width(@continuous_insertion_buffer)
+    bytesize = @continuous_insertion_buffer.bytesize
+    if @cursor == @cursor_max
+      @line += @continuous_insertion_buffer
+    else
+      @line = byteinsert(@line, @byte_pointer, @continuous_insertion_buffer)
+    end
+    @byte_pointer += bytesize
+    @cursor += width
+    @cursor_max += width
+    @continuous_insertion_buffer.clear
+  end
+
   private def ed_insert(key)
+    str = nil
+    width = nil
+    bytesize = nil
     if key.instance_of?(String)
       begin
         key.encode(Encoding::UTF_8)
       rescue Encoding::UndefinedConversionError
         return
       end
-      width = Reline::Unicode.get_mbchar_width(key)
-      if @cursor == @cursor_max
-        @line += key
-      else
-        @line = byteinsert(@line, @byte_pointer, key)
-      end
-      @byte_pointer += key.bytesize
-      @cursor += width
-      @cursor_max += width
+      str = key
+      bytesize = key.bytesize
     else
       begin
         key.chr.encode(Encoding::UTF_8)
       rescue Encoding::UndefinedConversionError
         return
       end
-      if @cursor == @cursor_max
-        @line += key.chr
-      else
-        @line = byteinsert(@line, @byte_pointer, key.chr)
-      end
-      width = Reline::Unicode.get_mbchar_width(key.chr)
-      @byte_pointer += 1
-      @cursor += width
-      @cursor_max += width
+      str = key.chr
+      bytesize = 1
     end
+    if Reline::IOGate.in_pasting?
+      @continuous_insertion_buffer << str
+      return
+    end
+    width = Reline::Unicode.get_mbchar_width(str)
+    if @cursor == @cursor_max
+      @line += str
+    else
+      @line = byteinsert(@line, @byte_pointer, str)
+    end
+    @byte_pointer += bytesize
+    @cursor += width
+    @cursor_max += width
   end
   alias_method :ed_digit, :ed_insert
   alias_method :self_insert, :ed_insert
@@ -1609,6 +1641,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L1641
   end
 
   private def ed_newline(key)
+    process_insert(force: true)
     if @is_multiline
       if @config.editing_mode_is?(:vi_command)
         if @line_index < (@buffer_of_lines.size - 1)
-- 
cgit v0.10.2


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

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