Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undo and redo should restore indentation #793

Merged
merged 2 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 15 additions & 28 deletions lib/reline/line_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ def reset_variables(prompt = '')
@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
Expand Down Expand Up @@ -1070,8 +1070,8 @@ def input_key(key)
@completion_journey_state = nil
end

push_input_lines unless @undoing
@undoing = false
push_input_lines unless @restoring
@restoring = false

if @in_pasting
clear_dialogs
Expand Down Expand Up @@ -1185,18 +1185,6 @@ def set_current_line(line, byte_pointer = nil)
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
Expand Down Expand Up @@ -2368,24 +2356,23 @@ def finish
@config.editing_mode = :vi_insert
end

private def undo(_key)
@undoing = true
private def move_undo_redo(direction)
@restoring = true
return unless (0..@input_lines.size - 1).cover?(@input_lines_position + direction)

return if @input_lines_position <= 0
@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

@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)
private def undo(_key)
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)
Expand Down
14 changes: 14 additions & 0 deletions test/reline/test_key_actor_emacs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1676,6 +1676,20 @@ def test_redo_with_multiline
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)
Expand Down
Loading