Skip to content

Commit beec339

Browse files
committed
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.
1 parent 167423b commit beec339

File tree

5 files changed

+58
-2
lines changed

5 files changed

+58
-2
lines changed

lib/reline.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,13 +235,19 @@ def readline(prompt = '', add_hist = false)
235235
line_editor.rerender
236236

237237
begin
238+
prev_pasting_state = false
238239
loop do
240+
prev_pasting_state = Reline::IOGate.in_pasting?
239241
read_io(config.keyseq_timeout) { |inputs|
240242
inputs.each { |c|
241243
line_editor.input_key(c)
242244
line_editor.rerender
243245
}
244246
}
247+
if prev_pasting_state == true and not Reline::IOGate.in_pasting? and not line_editor.finished?
248+
prev_pasting_state = false
249+
line_editor.rerender_all
250+
end
245251
break if line_editor.finished?
246252
end
247253
Reline::IOGate.move_cursor_column(0)

lib/reline/ansi.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,22 @@ def self.getc
8080
nil
8181
end
8282

83+
def self.in_pasting?
84+
not Reline::IOGate.empty_buffer?
85+
end
86+
87+
def self.empty_buffer?
88+
unless @@buf.empty?
89+
return false
90+
end
91+
rs, = IO.select([@@input], [], [], 0.00001)
92+
if rs and rs[0]
93+
false
94+
else
95+
true
96+
end
97+
end
98+
8399
def self.ungetc(c)
84100
@@buf.unshift(c)
85101
end

lib/reline/general_io.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ def self.set_screen_size(rows, columns)
6767
def self.set_winch_handler(&handler)
6868
end
6969

70+
def self.in_pasting?
71+
false
72+
end
73+
7074
def self.prep
7175
end
7276

lib/reline/line_editor.rb

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ def initialize(config, encoding)
5656
reset_variables(encoding: encoding)
5757
end
5858

59+
def simplified_rendering?
60+
if finished?
61+
false
62+
else
63+
not @rerender_all and not finished? and Reline::IOGate.in_pasting?
64+
end
65+
end
66+
5967
private def check_multiline_prompt(buffer, prompt)
6068
if @vi_arg
6169
prompt = "(arg: #{@vi_arg}) "
@@ -66,6 +74,7 @@ def initialize(config, encoding)
6674
else
6775
prompt = @prompt
6876
end
77+
return [prompt, calculate_width(prompt, true), [prompt] * buffer.size] if simplified_rendering?
6978
if @prompt_proc
7079
prompt_list = @prompt_proc.(buffer)
7180
prompt_list.map!{ prompt } if @vi_arg or @searching_prompt
@@ -297,6 +306,11 @@ def multiline_off
297306
@byte_pointer = new_byte_pointer
298307
end
299308

309+
def rerender_all
310+
@rerender_all = true
311+
rerender
312+
end
313+
300314
def rerender
301315
return if @line.nil?
302316
if @menu_info
@@ -523,6 +537,7 @@ def rerender
523537
end
524538
end
525539
Reline::IOGate.erase_after_cursor
540+
Reline::IOGate.move_cursor_column(0)
526541
if with_control
527542
# Just after rendring, so the cursor is on the last line.
528543
if finished?
@@ -537,7 +552,7 @@ def rerender
537552
end
538553

539554
private def modify_lines(before)
540-
return before if before.nil? || before.empty?
555+
return before if before.nil? || before.empty? || simplified_rendering?
541556

542557
if after = @output_modifier_proc&.call("#{before.join("\n")}\n", complete: finished?)
543558
after.lines("\n").map { |l| l.chomp('') }
@@ -836,7 +851,7 @@ def input_key(key)
836851
unless completion_occurs
837852
@completion_state = CompletionState::NORMAL
838853
end
839-
if @is_multiline and @auto_indent_proc
854+
if @is_multiline and @auto_indent_proc and not simplified_rendering?
840855
process_auto_indent
841856
end
842857
end
@@ -1038,6 +1053,7 @@ def finished?
10381053

10391054
def finish
10401055
@finished = true
1056+
@rerender_all = true
10411057
@config.reset
10421058
end
10431059

lib/reline/windows.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,20 @@ def self.ungetc(c)
199199
@@output_buf.unshift(c)
200200
end
201201

202+
def self.in_pasting?
203+
not self.empty_buffer?
204+
end
205+
206+
def self.empty_buffer?
207+
if not @@input_buf.empty?
208+
false
209+
elsif @@kbhit.call == 0
210+
true
211+
else
212+
false
213+
end
214+
end
215+
202216
def self.get_screen_size
203217
csbi = 0.chr * 22
204218
@@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi)

0 commit comments

Comments
 (0)