Skip to content

Commit

Permalink
[ruby/reline] Suppress callbacks in pasting
Browse files Browse the repository at this point in the history
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.

ruby/reline@beec3399a8
  • Loading branch information
aycabta committed Dec 4, 2020
1 parent 4291ff3 commit 55cc397
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 2 deletions.
6 changes: 6 additions & 0 deletions lib/reline.rb
Expand Up @@ -235,13 +235,19 @@ def readline(prompt = '', add_hist = false)
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)
Expand Down
16 changes: 16 additions & 0 deletions lib/reline/ansi.rb
Expand Up @@ -80,6 +80,22 @@ def self.getc
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
Expand Down
4 changes: 4 additions & 0 deletions lib/reline/general_io.rb
Expand Up @@ -67,6 +67,10 @@ def self.set_screen_size(rows, columns)
def self.set_winch_handler(&handler)
end

def self.in_pasting?
false
end

def self.prep
end

Expand Down
20 changes: 18 additions & 2 deletions lib/reline/line_editor.rb
Expand Up @@ -56,6 +56,14 @@ def initialize(config, encoding)
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}) "
Expand All @@ -66,6 +74,7 @@ def initialize(config, encoding)
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
Expand Down Expand Up @@ -297,6 +306,11 @@ def multiline_off
@byte_pointer = new_byte_pointer
end

def rerender_all
@rerender_all = true
rerender
end

def rerender
return if @line.nil?
if @menu_info
Expand Down Expand Up @@ -523,6 +537,7 @@ def rerender
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?
Expand All @@ -537,7 +552,7 @@ def rerender
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('') }
Expand Down Expand Up @@ -836,7 +851,7 @@ def input_key(key)
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
Expand Down Expand Up @@ -1038,6 +1053,7 @@ def finished?

def finish
@finished = true
@rerender_all = true
@config.reset
end

Expand Down
14 changes: 14 additions & 0 deletions lib/reline/windows.rb
Expand Up @@ -199,6 +199,20 @@ def self.ungetc(c)
@@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)
Expand Down

0 comments on commit 55cc397

Please sign in to comment.