Skip to content

Commit 1f469de

Browse files
committed
Support preposing and postposing for Reline.completion_proc
1 parent 3de32f2 commit 1f469de

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

lib/reline/line_editor.rb

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,8 +1158,25 @@ def input_key(key)
11581158

11591159
def call_completion_proc
11601160
result = retrieve_completion_block(true)
1161-
slice = result[1]
1162-
result = @completion_proc.(slice) if @completion_proc and slice
1161+
preposing, target, postposing = result
1162+
if @completion_proc and target
1163+
argnum = @completion_proc.parameters.inject(0) { |result, item|
1164+
case item.first
1165+
when :req, :opt
1166+
result + 1
1167+
when :rest
1168+
break 3
1169+
end
1170+
}
1171+
case argnum
1172+
when 1
1173+
result = @completion_proc.(target)
1174+
when 2
1175+
result = @completion_proc.(target, preposing)
1176+
when 3..Float::INFINITY
1177+
result = @completion_proc.(target, preposing, postposing)
1178+
end
1179+
end
11631180
Reline.core.instance_variable_set(:@completion_quote_character, nil)
11641181
result
11651182
end
@@ -1264,6 +1281,19 @@ def retrieve_completion_block(set_completion_quote_character = false)
12641281
end
12651282
target = before
12661283
end
1284+
if @is_multiline
1285+
if @previous_line_index
1286+
lines = whole_lines(index: @previous_line_index, line: @line)
1287+
else
1288+
lines = whole_lines
1289+
end
1290+
if @line_index > 0
1291+
preposing = lines[0..(@line_index - 1)].join("\n") + "\n" + preposing
1292+
end
1293+
if (lines.size - 1) > @line_index
1294+
postposing = postposing + "\n" + lines[(@line_index + 1)..-1].join("\n")
1295+
end
1296+
end
12671297
[preposing.encode(@encoding), target.encode(@encoding), postposing.encode(@encoding)]
12681298
end
12691299

test/reline/test_string_processing.rb

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,58 @@ def test_calculate_width_with_escape_sequence
2020
width = @line_editor.send(:calculate_width, "\1\e[31m\2RubyColor\1\e[34m\2 default string \1\e[m\2>", true)
2121
assert_equal('RubyColor default string >'.size, width)
2222
end
23+
24+
def test_completion_proc_with_preposing_and_postposing
25+
buf = ['def hoge', ' puts :aaa', 'end']
26+
27+
@line_editor.instance_variable_set(:@is_multiline, true)
28+
@line_editor.instance_variable_set(:@buffer_of_lines, buf)
29+
@line_editor.instance_variable_set(:@line, buf[1])
30+
@line_editor.instance_variable_set(:@byte_pointer, 3)
31+
@line_editor.instance_variable_set(:@cursor, 3)
32+
@line_editor.instance_variable_set(:@cursor_max, 11)
33+
@line_editor.instance_variable_set(:@line_index, 1)
34+
@line_editor.instance_variable_set(:@completion_proc, proc { |target|
35+
assert_equal('p', target)
36+
})
37+
@line_editor.__send__(:call_completion_proc)
38+
39+
@line_editor.instance_variable_set(:@is_multiline, true)
40+
@line_editor.instance_variable_set(:@buffer_of_lines, buf)
41+
@line_editor.instance_variable_set(:@line, buf[1])
42+
@line_editor.instance_variable_set(:@byte_pointer, 6)
43+
@line_editor.instance_variable_set(:@cursor, 6)
44+
@line_editor.instance_variable_set(:@cursor_max, 11)
45+
@line_editor.instance_variable_set(:@line_index, 1)
46+
@line_editor.instance_variable_set(:@completion_proc, proc { |target, pre, post|
47+
assert_equal('puts', target)
48+
assert_equal("def hoge\n ", pre)
49+
assert_equal(" :aaa\nend", post)
50+
})
51+
@line_editor.__send__(:call_completion_proc)
52+
53+
@line_editor.instance_variable_set(:@line, buf[0])
54+
@line_editor.instance_variable_set(:@byte_pointer, 6)
55+
@line_editor.instance_variable_set(:@cursor, 6)
56+
@line_editor.instance_variable_set(:@cursor_max, 8)
57+
@line_editor.instance_variable_set(:@line_index, 0)
58+
@line_editor.instance_variable_set(:@completion_proc, proc { |target, pre, post|
59+
assert_equal('ho', target)
60+
assert_equal('def ', pre)
61+
assert_equal("ge\n puts :aaa\nend", post)
62+
})
63+
@line_editor.__send__(:call_completion_proc)
64+
65+
@line_editor.instance_variable_set(:@line, buf[2])
66+
@line_editor.instance_variable_set(:@byte_pointer, 1)
67+
@line_editor.instance_variable_set(:@cursor, 1)
68+
@line_editor.instance_variable_set(:@cursor_max, 3)
69+
@line_editor.instance_variable_set(:@line_index, 2)
70+
@line_editor.instance_variable_set(:@completion_proc, proc { |target, pre, post|
71+
assert_equal('e', target)
72+
assert_equal("def hoge\n puts :aaa\n", pre)
73+
assert_equal('nd', post)
74+
})
75+
@line_editor.__send__(:call_completion_proc)
76+
end
2377
end

0 commit comments

Comments
 (0)