[ruby/reline] Undo and redo should restore indentation

(https://github.com/ruby/reline/pull/793)

* Undo and redo should restore indentation

Undo and redo should not perform auto indentation. It should not change the indentation. Instead, it should restore previous indentation.

* Rename ivar undoing(undoing or redoing) to restoring

https://github.com/ruby/reline/commit/6355a6e0b2
This commit is contained in:
tomoya ishida 2024-12-13 01:40:03 +09:00 committed by git
parent 776ec52148
commit 300be2b192
2 changed files with 30 additions and 29 deletions

View File

@ -252,7 +252,7 @@ class Reline::LineEditor
@rendered_screen = RenderedScreen.new(base_y: 0, lines: [], cursor_y: 0)
@input_lines = [[[""], 0, 0]]
@input_lines_position = 0
@undoing = false
@restoring = false
@prev_action_state = NullActionState
@next_action_state = NullActionState
reset_line
@ -1070,8 +1070,8 @@ class Reline::LineEditor
@completion_journey_state = nil
end
push_input_lines unless @undoing
@undoing = false
push_input_lines unless @restoring
@restoring = false
if @in_pasting
clear_dialogs
@ -1185,18 +1185,6 @@ class Reline::LineEditor
process_auto_indent
end
def set_current_lines(lines, byte_pointer = nil, line_index = 0)
cursor = current_byte_pointer_cursor
@buffer_of_lines = lines
@line_index = line_index
if byte_pointer
@byte_pointer = byte_pointer
else
calculate_nearest_cursor(cursor)
end
process_auto_indent
end
def retrieve_completion_block
quote_characters = Reline.completer_quote_characters
before = current_line.byteslice(0, @byte_pointer).grapheme_clusters
@ -2368,24 +2356,23 @@ class Reline::LineEditor
@config.editing_mode = :vi_insert
end
private def move_undo_redo(direction)
@restoring = true
return unless (0..@input_lines.size - 1).cover?(@input_lines_position + direction)
@input_lines_position += direction
buffer_of_lines, byte_pointer, line_index = @input_lines[@input_lines_position]
@buffer_of_lines = buffer_of_lines.dup
@line_index = line_index
@byte_pointer = byte_pointer
end
private def undo(_key)
@undoing = true
return if @input_lines_position <= 0
@input_lines_position -= 1
target_lines, target_cursor_x, target_cursor_y = @input_lines[@input_lines_position]
set_current_lines(target_lines.dup, target_cursor_x, target_cursor_y)
move_undo_redo(-1)
end
private def redo(_key)
@undoing = true
return if @input_lines_position >= @input_lines.size - 1
@input_lines_position += 1
target_lines, target_cursor_x, target_cursor_y = @input_lines[@input_lines_position]
set_current_lines(target_lines.dup, target_cursor_x, target_cursor_y)
move_undo_redo(+1)
end
private def prev_action_state_value(type)

View File

@ -1676,6 +1676,20 @@ class Reline::KeyActor::EmacsTest < Reline::TestCase
assert_line_around_cursor('3', '')
end
def test_undo_redo_restores_indentation
@line_editor.multiline_on
@line_editor.confirm_multiline_termination_proc = proc {}
input_keys(" 1", false)
assert_whole_lines([' 1'])
input_keys("2", false)
assert_whole_lines([' 12'])
@line_editor.auto_indent_proc = proc { 2 }
input_keys("\C-_", false)
assert_whole_lines([' 1'])
input_keys("\M-\C-_", false)
assert_whole_lines([' 12'])
end
def test_redo_with_many_times
str = "a" + "b" * 98 + "c"
input_keys(str, false)