[前][次][番号順一覧][スレッド一覧]

ruby-changes:63947

From: aycabta <ko1@a...>
Date: Sat, 5 Dec 2020 03:09:45 +0900 (JST)
Subject: [ruby-changes:63947] b545ab219b (master): [ruby/reline] Stop rerendering whole screen when adding newline at end of buffer

https://git.ruby-lang.org/ruby.git/commit/?id=b545ab219b

From b545ab219b40323373596eb45b43f2599a7a3c61 Mon Sep 17 00:00:00 2001
From: aycabta <aycabta@g...>
Date: Thu, 19 Nov 2020 22:59:16 +0900
Subject: [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

diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index c7b4e47..f6d00ae 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -187,6 +187,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L187
     @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 https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L353
     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 https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L1132
 
   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)
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]