diff options
author | aycabta <aycabta@gmail.com> | 2020-11-19 22:59:16 +0900 |
---|---|---|
committer | aycabta <aycabta@gmail.com> | 2020-12-05 02:58:59 +0900 |
commit | b545ab219b40323373596eb45b43f2599a7a3c61 (patch) | |
tree | 7dfa83f23aca13e7a61547972750b3bacb790e82 /lib | |
parent | fb2fda9a27ed96d5100897e93cc31e155b9c41a8 (diff) |
[ruby/reline] Stop rerendering whole screen when adding newline at end of buffer
The rendering time in IRB has been reduced as follows:
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.33sec -> 0.22sec
https://github.com/ruby/reline/commit/496c6a1892
Diffstat (limited to 'lib')
-rw-r--r-- | lib/reline/line_editor.rb | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb index c7b4e47ddb..f6d00ae41a 100644 --- a/lib/reline/line_editor.rb +++ b/lib/reline/line_editor.rb @@ -187,6 +187,7 @@ class Reline::LineEditor @first_prompt = true @searching_prompt = nil @first_char = true + @add_newline_to_end_of_buffer = false @eof = false @continuous_insertion_buffer = String.new(encoding: @encoding) reset_line @@ -352,7 +353,22 @@ class Reline::LineEditor end new_highest_in_this = calculate_height_by_width(prompt_width + calculate_width(@line.nil? ? '' : @line)) # FIXME: end of logical line sometimes breaks - if @previous_line_index or new_highest_in_this != @highest_in_this + if @add_newline_to_end_of_buffer + scroll_down(1) + new_lines = whole_lines(index: @previous_line_index, line: @line) + prompt, prompt_width, prompt_list = check_multiline_prompt(new_lines, prompt) + @buffer_of_lines[@previous_line_index] = @line + @line = @buffer_of_lines[@line_index] + render_partial(prompt, prompt_width, @line, false) + @cursor = @cursor_max = calculate_width(@line) + @byte_pointer = @line.bytesize + @highest_in_all += @highest_in_this + @highest_in_this = calculate_height_by_width(prompt_width + @cursor_max) + @first_line_started_from += @started_from + 1 + @started_from = calculate_height_by_width(prompt_width + @cursor) - 1 + @previous_line_index = nil + @add_newline_to_end_of_buffer = false + elsif @previous_line_index or new_highest_in_this != @highest_in_this if @previous_line_index new_lines = whole_lines(index: @previous_line_index, line: @line) else @@ -1116,6 +1132,9 @@ class Reline::LineEditor private def key_newline(key) if @is_multiline + if (@buffer_of_lines.size - 1) == @line_index and @line.bytesize == @byte_pointer + @add_newline_to_end_of_buffer = true + end next_line = @line.byteslice(@byte_pointer, @line.bytesize - @byte_pointer) cursor_line = @line.byteslice(0, @byte_pointer) insert_new_line(cursor_line, next_line) |