ruby-changes:63933
From: aycabta <ko1@a...>
Date: Sat, 5 Dec 2020 03:09:32 +0900 (JST)
Subject: [ruby-changes:63933] 55cc397a87 (master): [ruby/reline] Suppress callbacks in pasting
https://git.ruby-lang.org/ruby.git/commit/?id=55cc397a87 From 55cc397a87dbfaa5d95168ce05f9a0d20339c657 Mon Sep 17 00:00:00 2001 From: aycabta <aycabta@g...> Date: Tue, 20 Oct 2020 08:39:12 +0900 Subject: [ruby/reline] Suppress callbacks in pasting IRB uses Reline's 3 dynamic real-time callbacks with calling Ripper; output_modifier_proc, prompt_proc, and auto_indent_proc. These processing times make the paste time too long. https://github.com/ruby/reline/commit/beec3399a8 diff --git a/lib/reline.rb b/lib/reline.rb index eb18d0d..2862f5b 100644 --- a/lib/reline.rb +++ b/lib/reline.rb @@ -235,13 +235,19 @@ module Reline https://github.com/ruby/ruby/blob/trunk/lib/reline.rb#L235 line_editor.rerender begin + prev_pasting_state = false loop do + prev_pasting_state = Reline::IOGate.in_pasting? read_io(config.keyseq_timeout) { |inputs| inputs.each { |c| line_editor.input_key(c) line_editor.rerender } } + if prev_pasting_state == true and not Reline::IOGate.in_pasting? and not line_editor.finished? + prev_pasting_state = false + line_editor.rerender_all + end break if line_editor.finished? end Reline::IOGate.move_cursor_column(0) diff --git a/lib/reline/ansi.rb b/lib/reline/ansi.rb index 80fccd7..f11dbb8 100644 --- a/lib/reline/ansi.rb +++ b/lib/reline/ansi.rb @@ -80,6 +80,22 @@ class Reline::ANSI https://github.com/ruby/ruby/blob/trunk/lib/reline/ansi.rb#L80 nil end + def self.in_pasting? + not Reline::IOGate.empty_buffer? + end + + def self.empty_buffer? + unless @@buf.empty? + return false + end + rs, = IO.select([@@input], [], [], 0.00001) + if rs and rs[0] + false + else + true + end + end + def self.ungetc(c) @@buf.unshift(c) end diff --git a/lib/reline/general_io.rb b/lib/reline/general_io.rb index 85f1f13..3b40888 100644 --- a/lib/reline/general_io.rb +++ b/lib/reline/general_io.rb @@ -67,6 +67,10 @@ class Reline::GeneralIO https://github.com/ruby/ruby/blob/trunk/lib/reline/general_io.rb#L67 def self.set_winch_handler(&handler) end + def self.in_pasting? + false + end + def self.prep end diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb index e5ecc8b..5558a1b 100644 --- a/lib/reline/line_editor.rb +++ b/lib/reline/line_editor.rb @@ -56,6 +56,14 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L56 reset_variables(encoding: encoding) end + def simplified_rendering? + if finished? + false + else + not @rerender_all and not finished? and Reline::IOGate.in_pasting? + end + end + private def check_multiline_prompt(buffer, prompt) if @vi_arg prompt = "(arg: #{@vi_arg}) " @@ -66,6 +74,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L74 else prompt = @prompt end + return [prompt, calculate_width(prompt, true), [prompt] * buffer.size] if simplified_rendering? if @prompt_proc prompt_list = @prompt_proc.(buffer) prompt_list.map!{ prompt } if @vi_arg or @searching_prompt @@ -297,6 +306,11 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L306 @byte_pointer = new_byte_pointer end + def rerender_all + @rerender_all = true + rerender + end + def rerender return if @line.nil? if @menu_info @@ -523,6 +537,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L537 end end Reline::IOGate.erase_after_cursor + Reline::IOGate.move_cursor_column(0) if with_control # Just after rendring, so the cursor is on the last line. if finished? @@ -537,7 +552,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L552 end private def modify_lines(before) - return before if before.nil? || before.empty? + return before if before.nil? || before.empty? || simplified_rendering? if after = @output_modifier_proc&.call("#{before.join("\n")}\n", complete: finished?) after.lines("\n").map { |l| l.chomp('') } @@ -836,7 +851,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L851 unless completion_occurs @completion_state = CompletionState::NORMAL end - if @is_multiline and @auto_indent_proc + if @is_multiline and @auto_indent_proc and not simplified_rendering? process_auto_indent end end @@ -1038,6 +1053,7 @@ class Reline::LineEditor https://github.com/ruby/ruby/blob/trunk/lib/reline/line_editor.rb#L1053 def finish @finished = true + @rerender_all = true @config.reset end diff --git a/lib/reline/windows.rb b/lib/reline/windows.rb index 2a406e3..b09290b 100644 --- a/lib/reline/windows.rb +++ b/lib/reline/windows.rb @@ -199,6 +199,20 @@ class Reline::Windows https://github.com/ruby/ruby/blob/trunk/lib/reline/windows.rb#L199 @@output_buf.unshift(c) end + def self.in_pasting? + not self.empty_buffer? + end + + def self.empty_buffer? + if not @@input_buf.empty? + false + elsif @@kbhit.call == 0 + true + else + false + end + end + def self.get_screen_size csbi = 0.chr * 22 @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi) -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/