summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authoraycabta <aycabta@gmail.com>2020-10-20 08:39:12 +0900
committeraycabta <aycabta@gmail.com>2020-12-05 02:58:58 +0900
commit55cc397a87dbfaa5d95168ce05f9a0d20339c657 (patch)
tree3f5fa43ad24e444e52e50fc7e32ae66b9483a3e2 /lib
parent4291ff370f88c9cbb83913b1d18e3f6206758b14 (diff)
[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
Diffstat (limited to 'lib')
-rw-r--r--lib/reline.rb6
-rw-r--r--lib/reline/ansi.rb16
-rw-r--r--lib/reline/general_io.rb4
-rw-r--r--lib/reline/line_editor.rb20
-rw-r--r--lib/reline/windows.rb14
5 files changed, 58 insertions, 2 deletions
diff --git a/lib/reline.rb b/lib/reline.rb
index eb18d0d075..2862f5bc64 100644
--- a/lib/reline.rb
+++ b/lib/reline.rb
@@ -235,13 +235,19 @@ module Reline
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 80fccd74f9..f11dbb80f4 100644
--- a/lib/reline/ansi.rb
+++ b/lib/reline/ansi.rb
@@ -80,6 +80,22 @@ class Reline::ANSI
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 85f1f13eed..3b40888bed 100644
--- a/lib/reline/general_io.rb
+++ b/lib/reline/general_io.rb
@@ -67,6 +67,10 @@ class Reline::GeneralIO
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 e5ecc8bbcb..5558a1bb07 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -56,6 +56,14 @@ class Reline::LineEditor
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
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
@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
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
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
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
def finish
@finished = true
+ @rerender_all = true
@config.reset
end
diff --git a/lib/reline/windows.rb b/lib/reline/windows.rb
index 2a406e39d3..b09290bcf3 100644
--- a/lib/reline/windows.rb
+++ b/lib/reline/windows.rb
@@ -199,6 +199,20 @@ class Reline::Windows
@@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)