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/