Skip to content

Commit

Permalink
Undo and redo should restore indentation (#793)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
tompng authored Dec 12, 2024
1 parent a1943da commit 6355a6e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 28 deletions.
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

0 comments on commit 6355a6e

Please sign in to comment.