summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/reline/line_editor.rb81
1 files changed, 57 insertions, 24 deletions
diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index 5558a1bb07..325475f4b9 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -187,6 +187,7 @@ class Reline::LineEditor
@searching_prompt = nil
@first_char = true
@eof = false
+ @continuous_insertion_buffer = String.new(encoding: @encoding)
reset_line
end
@@ -728,6 +729,18 @@ class Reline::LineEditor
method_obj and method_obj.parameters.length != 1
end
+ def wrap_method_call(method_symbol, method_obj, key)
+ if @config.editing_mode_is?(:emacs, :vi_insert) and @waiting_proc.nil? and @waiting_operator_proc.nil?
+ not_insertion = method_symbol != :ed_insert
+ process_insert(force: not_insertion)
+ end
+ if @vi_arg
+ method_obj.(key, arg: @vi_arg)
+ else
+ method_obj.(key)
+ end
+ end
+
private def process_key(key, method_symbol)
if method_symbol and respond_to?(method_symbol, true)
method_obj = method(method_symbol)
@@ -737,10 +750,10 @@ class Reline::LineEditor
if method_symbol and key.is_a?(Symbol)
if @vi_arg and argumentable?(method_obj)
run_for_operators(key, method_symbol) do
- method_obj.(key, arg: @vi_arg)
+ wrap_method_call(method_symbol, method_obj, key)
end
else
- method_obj&.(key)
+ wrap_method_call(method_symbol, method_obj, key) if method_obj
end
@kill_ring.process
@vi_arg = nil
@@ -750,12 +763,12 @@ class Reline::LineEditor
else
if argumentable?(method_obj)
run_for_operators(key, method_symbol) do
- method_obj.(key, arg: @vi_arg)
+ wrap_method_call(method_symbol, method_obj, key)
end
elsif @waiting_proc
@waiting_proc.(key)
elsif method_obj
- method_obj.(key)
+ wrap_method_call(method_symbol, method_obj, key)
else
ed_insert(key)
end
@@ -767,10 +780,10 @@ class Reline::LineEditor
@kill_ring.process
elsif method_obj
if method_symbol == :ed_argument_digit
- method_obj.(key)
+ wrap_method_call(method_symbol, method_obj, key)
else
run_for_operators(key, method_symbol) do
- method_obj.(key)
+ wrap_method_call(method_symbol, method_obj, key)
end
end
@kill_ring.process
@@ -832,6 +845,7 @@ class Reline::LineEditor
result = call_completion_proc
if result.is_a?(Array)
completion_occurs = true
+ process_insert
complete(result)
end
end
@@ -840,6 +854,7 @@ class Reline::LineEditor
result = call_completion_proc
if result.is_a?(Array)
completion_occurs = true
+ process_insert
move_completed_list(result, "\C-p".ord == key.char ? :up : :down)
end
end
@@ -1092,38 +1107,55 @@ class Reline::LineEditor
private def ed_unassigned(key) end # do nothing
+ private def process_insert(force: false)
+ return if @continuous_insertion_buffer.empty? or (Reline::IOGate.in_pasting? and not force)
+ width = Reline::Unicode.calculate_width(@continuous_insertion_buffer)
+ bytesize = @continuous_insertion_buffer.bytesize
+ if @cursor == @cursor_max
+ @line += @continuous_insertion_buffer
+ else
+ @line = byteinsert(@line, @byte_pointer, @continuous_insertion_buffer)
+ end
+ @byte_pointer += bytesize
+ @cursor += width
+ @cursor_max += width
+ @continuous_insertion_buffer.clear
+ end
+
private def ed_insert(key)
+ str = nil
+ width = nil
+ bytesize = nil
if key.instance_of?(String)
begin
key.encode(Encoding::UTF_8)
rescue Encoding::UndefinedConversionError
return
end
- width = Reline::Unicode.get_mbchar_width(key)
- if @cursor == @cursor_max
- @line += key
- else
- @line = byteinsert(@line, @byte_pointer, key)
- end
- @byte_pointer += key.bytesize
- @cursor += width
- @cursor_max += width
+ str = key
+ bytesize = key.bytesize
else
begin
key.chr.encode(Encoding::UTF_8)
rescue Encoding::UndefinedConversionError
return
end
- if @cursor == @cursor_max
- @line += key.chr
- else
- @line = byteinsert(@line, @byte_pointer, key.chr)
- end
- width = Reline::Unicode.get_mbchar_width(key.chr)
- @byte_pointer += 1
- @cursor += width
- @cursor_max += width
+ str = key.chr
+ bytesize = 1
end
+ if Reline::IOGate.in_pasting?
+ @continuous_insertion_buffer << str
+ return
+ end
+ width = Reline::Unicode.get_mbchar_width(str)
+ if @cursor == @cursor_max
+ @line += str
+ else
+ @line = byteinsert(@line, @byte_pointer, str)
+ end
+ @byte_pointer += bytesize
+ @cursor += width
+ @cursor_max += width
end
alias_method :ed_digit, :ed_insert
alias_method :self_insert, :ed_insert
@@ -1609,6 +1641,7 @@ class Reline::LineEditor
end
private def ed_newline(key)
+ process_insert(force: true)
if @is_multiline
if @config.editing_mode_is?(:vi_command)
if @line_index < (@buffer_of_lines.size - 1)