summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authoraycabta <aycabta@gmail.com>2020-11-19 22:59:16 +0900
committeraycabta <aycabta@gmail.com>2020-12-05 02:58:59 +0900
commitb545ab219b40323373596eb45b43f2599a7a3c61 (patch)
tree7dfa83f23aca13e7a61547972750b3bacb790e82 /lib
parentfb2fda9a27ed96d5100897e93cc31e155b9c41a8 (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.rb21
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)