1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

[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@hyplex.us",
    "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
This commit is contained in:
aycabta 2020-10-31 16:45:15 +09:00
parent 76cac4c05a
commit 266ffdde8e

View file

@ -187,6 +187,7 @@ class Reline::LineEditor
@searching_prompt = nil @searching_prompt = nil
@first_char = true @first_char = true
@eof = false @eof = false
@continuous_insertion_buffer = String.new(encoding: @encoding)
reset_line reset_line
end end
@ -728,6 +729,18 @@ class Reline::LineEditor
method_obj and method_obj.parameters.length != 1 method_obj and method_obj.parameters.length != 1
end 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) private def process_key(key, method_symbol)
if method_symbol and respond_to?(method_symbol, true) if method_symbol and respond_to?(method_symbol, true)
method_obj = method(method_symbol) method_obj = method(method_symbol)
@ -737,10 +750,10 @@ class Reline::LineEditor
if method_symbol and key.is_a?(Symbol) if method_symbol and key.is_a?(Symbol)
if @vi_arg and argumentable?(method_obj) if @vi_arg and argumentable?(method_obj)
run_for_operators(key, method_symbol) do run_for_operators(key, method_symbol) do
method_obj.(key, arg: @vi_arg) wrap_method_call(method_symbol, method_obj, key)
end end
else else
method_obj&.(key) wrap_method_call(method_symbol, method_obj, key) if method_obj
end end
@kill_ring.process @kill_ring.process
@vi_arg = nil @vi_arg = nil
@ -750,12 +763,12 @@ class Reline::LineEditor
else else
if argumentable?(method_obj) if argumentable?(method_obj)
run_for_operators(key, method_symbol) do run_for_operators(key, method_symbol) do
method_obj.(key, arg: @vi_arg) wrap_method_call(method_symbol, method_obj, key)
end end
elsif @waiting_proc elsif @waiting_proc
@waiting_proc.(key) @waiting_proc.(key)
elsif method_obj elsif method_obj
method_obj.(key) wrap_method_call(method_symbol, method_obj, key)
else else
ed_insert(key) ed_insert(key)
end end
@ -767,10 +780,10 @@ class Reline::LineEditor
@kill_ring.process @kill_ring.process
elsif method_obj elsif method_obj
if method_symbol == :ed_argument_digit if method_symbol == :ed_argument_digit
method_obj.(key) wrap_method_call(method_symbol, method_obj, key)
else else
run_for_operators(key, method_symbol) do run_for_operators(key, method_symbol) do
method_obj.(key) wrap_method_call(method_symbol, method_obj, key)
end end
end end
@kill_ring.process @kill_ring.process
@ -832,6 +845,7 @@ class Reline::LineEditor
result = call_completion_proc result = call_completion_proc
if result.is_a?(Array) if result.is_a?(Array)
completion_occurs = true completion_occurs = true
process_insert
complete(result) complete(result)
end end
end end
@ -840,6 +854,7 @@ class Reline::LineEditor
result = call_completion_proc result = call_completion_proc
if result.is_a?(Array) if result.is_a?(Array)
completion_occurs = true completion_occurs = true
process_insert
move_completed_list(result, "\C-p".ord == key.char ? :up : :down) move_completed_list(result, "\C-p".ord == key.char ? :up : :down)
end end
end end
@ -1092,38 +1107,55 @@ class Reline::LineEditor
private def ed_unassigned(key) end # do nothing 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) private def ed_insert(key)
str = nil
width = nil
bytesize = nil
if key.instance_of?(String) if key.instance_of?(String)
begin begin
key.encode(Encoding::UTF_8) key.encode(Encoding::UTF_8)
rescue Encoding::UndefinedConversionError rescue Encoding::UndefinedConversionError
return return
end end
width = Reline::Unicode.get_mbchar_width(key) str = key
if @cursor == @cursor_max bytesize = key.bytesize
@line += key
else
@line = byteinsert(@line, @byte_pointer, key)
end
@byte_pointer += key.bytesize
@cursor += width
@cursor_max += width
else else
begin begin
key.chr.encode(Encoding::UTF_8) key.chr.encode(Encoding::UTF_8)
rescue Encoding::UndefinedConversionError rescue Encoding::UndefinedConversionError
return return
end end
if @cursor == @cursor_max str = key.chr
@line += key.chr bytesize = 1
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
end 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 end
alias_method :ed_digit, :ed_insert alias_method :ed_digit, :ed_insert
alias_method :self_insert, :ed_insert alias_method :self_insert, :ed_insert
@ -1609,6 +1641,7 @@ class Reline::LineEditor
end end
private def ed_newline(key) private def ed_newline(key)
process_insert(force: true)
if @is_multiline if @is_multiline
if @config.editing_mode_is?(:vi_command) if @config.editing_mode_is?(:vi_command)
if @line_index < (@buffer_of_lines.size - 1) if @line_index < (@buffer_of_lines.size - 1)