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
@first_char = true
@eof = false
@continuous_insertion_buffer = String.new(encoding: @encoding)
reset_line
end
@ -728,6 +729,18 @@ class Reline::LineEditor
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
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
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
@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
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
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
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
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)