[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
This commit is contained in:
aycabta 2020-10-20 08:39:12 +09:00
Родитель 4291ff370f
Коммит 55cc397a87
5 изменённых файлов: 58 добавлений и 2 удалений

Просмотреть файл

@ -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)

Просмотреть файл

@ -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

Просмотреть файл

@ -67,6 +67,10 @@ class Reline::GeneralIO
def self.set_winch_handler(&handler)
end
def self.in_pasting?
false
end
def self.prep
end

Просмотреть файл

@ -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

Просмотреть файл

@ -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)