summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/reline/line_editor.rb34
-rw-r--r--test/reline/test_string_processing.rb54
2 files changed, 86 insertions, 2 deletions
diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index 870b89b550..4e5860ceb9 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -1158,8 +1158,25 @@ class Reline::LineEditor
def call_completion_proc
result = retrieve_completion_block(true)
- slice = result[1]
- result = @completion_proc.(slice) if @completion_proc and slice
+ preposing, target, postposing = result
+ if @completion_proc and target
+ argnum = @completion_proc.parameters.inject(0) { |result, item|
+ case item.first
+ when :req, :opt
+ result + 1
+ when :rest
+ break 3
+ end
+ }
+ case argnum
+ when 1
+ result = @completion_proc.(target)
+ when 2
+ result = @completion_proc.(target, preposing)
+ when 3..Float::INFINITY
+ result = @completion_proc.(target, preposing, postposing)
+ end
+ end
Reline.core.instance_variable_set(:@completion_quote_character, nil)
result
end
@@ -1264,6 +1281,19 @@ class Reline::LineEditor
end
target = before
end
+ if @is_multiline
+ if @previous_line_index
+ lines = whole_lines(index: @previous_line_index, line: @line)
+ else
+ lines = whole_lines
+ end
+ if @line_index > 0
+ preposing = lines[0..(@line_index - 1)].join("\n") + "\n" + preposing
+ end
+ if (lines.size - 1) > @line_index
+ postposing = postposing + "\n" + lines[(@line_index + 1)..-1].join("\n")
+ end
+ end
[preposing.encode(@encoding), target.encode(@encoding), postposing.encode(@encoding)]
end
diff --git a/test/reline/test_string_processing.rb b/test/reline/test_string_processing.rb
index e76fa384f2..0e0ee9cc04 100644
--- a/test/reline/test_string_processing.rb
+++ b/test/reline/test_string_processing.rb
@@ -20,4 +20,58 @@ class Reline::LineEditor::StringProcessingTest < Reline::TestCase
width = @line_editor.send(:calculate_width, "\1\e[31m\2RubyColor\1\e[34m\2 default string \1\e[m\2>", true)
assert_equal('RubyColor default string >'.size, width)
end
+
+ def test_completion_proc_with_preposing_and_postposing
+ buf = ['def hoge', ' puts :aaa', 'end']
+
+ @line_editor.instance_variable_set(:@is_multiline, true)
+ @line_editor.instance_variable_set(:@buffer_of_lines, buf)
+ @line_editor.instance_variable_set(:@line, buf[1])
+ @line_editor.instance_variable_set(:@byte_pointer, 3)
+ @line_editor.instance_variable_set(:@cursor, 3)
+ @line_editor.instance_variable_set(:@cursor_max, 11)
+ @line_editor.instance_variable_set(:@line_index, 1)
+ @line_editor.instance_variable_set(:@completion_proc, proc { |target|
+ assert_equal('p', target)
+ })
+ @line_editor.__send__(:call_completion_proc)
+
+ @line_editor.instance_variable_set(:@is_multiline, true)
+ @line_editor.instance_variable_set(:@buffer_of_lines, buf)
+ @line_editor.instance_variable_set(:@line, buf[1])
+ @line_editor.instance_variable_set(:@byte_pointer, 6)
+ @line_editor.instance_variable_set(:@cursor, 6)
+ @line_editor.instance_variable_set(:@cursor_max, 11)
+ @line_editor.instance_variable_set(:@line_index, 1)
+ @line_editor.instance_variable_set(:@completion_proc, proc { |target, pre, post|
+ assert_equal('puts', target)
+ assert_equal("def hoge\n ", pre)
+ assert_equal(" :aaa\nend", post)
+ })
+ @line_editor.__send__(:call_completion_proc)
+
+ @line_editor.instance_variable_set(:@line, buf[0])
+ @line_editor.instance_variable_set(:@byte_pointer, 6)
+ @line_editor.instance_variable_set(:@cursor, 6)
+ @line_editor.instance_variable_set(:@cursor_max, 8)
+ @line_editor.instance_variable_set(:@line_index, 0)
+ @line_editor.instance_variable_set(:@completion_proc, proc { |target, pre, post|
+ assert_equal('ho', target)
+ assert_equal('def ', pre)
+ assert_equal("ge\n puts :aaa\nend", post)
+ })
+ @line_editor.__send__(:call_completion_proc)
+
+ @line_editor.instance_variable_set(:@line, buf[2])
+ @line_editor.instance_variable_set(:@byte_pointer, 1)
+ @line_editor.instance_variable_set(:@cursor, 1)
+ @line_editor.instance_variable_set(:@cursor_max, 3)
+ @line_editor.instance_variable_set(:@line_index, 2)
+ @line_editor.instance_variable_set(:@completion_proc, proc { |target, pre, post|
+ assert_equal('e', target)
+ assert_equal("def hoge\n puts :aaa\n", pre)
+ assert_equal('nd', post)
+ })
+ @line_editor.__send__(:call_completion_proc)
+ end
end