diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/reline.rb | 6 | ||||
-rw-r--r-- | lib/reline/ansi.rb | 16 | ||||
-rw-r--r-- | lib/reline/general_io.rb | 4 | ||||
-rw-r--r-- | lib/reline/line_editor.rb | 20 | ||||
-rw-r--r-- | lib/reline/windows.rb | 14 |
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) |