[ruby/reline] Fix wrong indent number in prompt. whole_lines has

duplicated line.
(https://github.com/ruby/reline/pull/460)

* whole_lines should consider prev_line_index, and must not duplicate last_line

* Add test for lines passed to dynamic prompt proc

* Refactor whole_lines parameters used in test helper

* Remove whole_line's arguments
This commit is contained in:
tomoya ishida 2023-02-27 19:21:25 +09:00 коммит произвёл git
Родитель 2cbe1f3ebc
Коммит 4f611df3f7
4 изменённых файлов: 31 добавлений и 41 удалений

Просмотреть файл

@ -450,12 +450,8 @@ class Reline::LineEditor
Reline::IOGate.move_cursor_up(@first_line_started_from + @started_from - @scroll_partial_screen)
Reline::IOGate.move_cursor_column(0)
@scroll_partial_screen = nil
prompt, prompt_width, prompt_list = check_multiline_prompt(whole_lines)
if @previous_line_index
new_lines = whole_lines(index: @previous_line_index, line: @line)
else
new_lines = whole_lines
end
new_lines = whole_lines
prompt, prompt_width, prompt_list = check_multiline_prompt(new_lines)
modify_lines(new_lines).each_with_index do |line, index|
@output.write "#{prompt_list ? prompt_list[index] : prompt}#{line}\r\n"
Reline::IOGate.erase_after_cursor
@ -491,11 +487,7 @@ class Reline::LineEditor
if @is_multiline
if finished?
# Always rerender on finish because output_modifier_proc may return a different output.
if @previous_line_index
new_lines = whole_lines(index: @previous_line_index, line: @line)
else
new_lines = whole_lines
end
new_lines = whole_lines
line = modify_lines(new_lines)[@line_index]
clear_dialog
prompt, prompt_width, prompt_list = check_multiline_prompt(new_lines)
@ -1025,11 +1017,7 @@ class Reline::LineEditor
end
private def rerender_changed_current_line
if @previous_line_index
new_lines = whole_lines(index: @previous_line_index, line: @line)
else
new_lines = whole_lines
end
new_lines = whole_lines
prompt, prompt_width, prompt_list = check_multiline_prompt(new_lines)
all_height = calculate_height_by_lines(new_lines, prompt_list || prompt)
diff = all_height - @highest_in_all
@ -1710,7 +1698,7 @@ class Reline::LineEditor
return if not @check_new_auto_indent and @previous_line_index # move cursor up or down
if @check_new_auto_indent and @previous_line_index and @previous_line_index > 0 and @line_index > @previous_line_index
# Fix indent of a line when a newline is inserted to the next
new_lines = whole_lines(index: @previous_line_index, line: @line)
new_lines = whole_lines
new_indent = @auto_indent_proc.(new_lines[0..-3].push(''), @line_index - 1, 0, true)
md = @line.match(/\A */)
prev_indent = md[0].count(' ')
@ -1725,11 +1713,7 @@ class Reline::LineEditor
@line = ' ' * new_indent + @line.lstrip
end
end
if @previous_line_index
new_lines = whole_lines(index: @previous_line_index, line: @line)
else
new_lines = whole_lines
end
new_lines = whole_lines
new_indent = @auto_indent_proc.(new_lines, @line_index, @byte_pointer, @check_new_auto_indent)
if new_indent&.>= 0
md = new_lines[@line_index].match(/\A */)
@ -1816,11 +1800,7 @@ class Reline::LineEditor
target = before
end
if @is_multiline
if @previous_line_index
lines = whole_lines(index: @previous_line_index, line: @line)
else
lines = whole_lines
end
lines = whole_lines
if @line_index > 0
preposing = lines[0..(@line_index - 1)].join("\n") + "\n" + preposing
end
@ -1920,9 +1900,10 @@ class Reline::LineEditor
@cursor_max = calculate_width(@line)
end
def whole_lines(index: @line_index, line: @line)
def whole_lines
index = @previous_line_index || @line_index
temp_lines = @buffer_of_lines.dup
temp_lines[index] = line
temp_lines[index] = @line
temp_lines
end
@ -1930,11 +1911,7 @@ class Reline::LineEditor
if @buffer_of_lines.size == 1 and @line.nil?
nil
else
if @previous_line_index
whole_lines(index: @previous_line_index, line: @line).join("\n")
else
whole_lines.join("\n")
end
whole_lines.join("\n")
end
end

Просмотреть файл

@ -157,13 +157,7 @@ class Reline::TestCase < Test::Unit::TestCase
end
def assert_whole_lines(expected)
previous_line_index = @line_editor.instance_variable_get(:@previous_line_index)
if previous_line_index
lines = @line_editor.whole_lines(index: previous_line_index)
else
lines = @line_editor.whole_lines
end
assert_equal(expected, lines)
assert_equal(expected, @line_editor.whole_lines)
end
def assert_key_binding(input, method_symbol, editing_modes = [:emacs, :vi_insert, :vi_command])

Просмотреть файл

@ -52,6 +52,13 @@ opt.on('--color-bold') {
output.gsub(/./) { |c| "\e[1m#{c}\e[0m" }
}
}
opt.on('--dynamic-prompt-show-line') {
Reline.prompt_proc = proc { |lines|
lines.map { |l|
'[%4.4s]> ' % l
}
}
}
opt.on('--auto-indent') {
Reline.auto_indent_proc = lambda do |lines, line_index, byte_pointer, is_newline|
AutoIndent.calculate_indent(lines, line_index, byte_pointer, is_newline)

Просмотреть файл

@ -1335,6 +1335,18 @@ begin
EOC
end
def test_lines_passed_to_dynamic_prompt
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dynamic-prompt-show-line}, startup_message: 'Multiline REPL.')
write("if true")
write("\n")
close
assert_screen(<<~EOC)
Multiline REPL.
[if t]> if true
[ ]>
EOC
end
def test_clear_dialog_when_just_move_cursor_at_last_line
start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
write("class A\n 3\nend\n")