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:
parent
76cac4c05a
commit
266ffdde8e
1 changed files with 57 additions and 24 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue