From af1b59981872fc3339a4ae092a69b95b90e6305a Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Wed, 3 Apr 2024 12:05:09 +0200 Subject: [PATCH] On redo, restore pre-undo cursor position --- CHANGELOG.rst | 1 + src/editable_line.rs | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 994dabd18..8bb49aee8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -234,6 +234,7 @@ Interactive improvements - The completion pager will no longer sometimes skip the last entry when moving through a long list (:issue:`9833`). - The interactive ``history delete`` interface now allows specifying index ranges like "1..5" (:issue:`9736`), and ``history delete --exact`` now properly saves the history (:issue:`10066`). - Command completion will now call the stock ``manpath`` on macOS, instead of a potential Homebrew version. This prevents awkward error messages (:issue:`9817`). +- the ``redo`` special input function restores the pre-undo cursor position. - A new bind function ``history-pager-delete``, bound to :kbd:`Shift` + :kbd:`Delete` by default, will delete the currently-selected history pager item from history (:issue:`9454`). - ``fish_key_reader`` will now use printable characters as-is, so pressing "รถ" no longer leads to it telling you to bind ``\u00F6`` (:issue:`9986`). - ``open`` can be used to launch terminal programs again, as an ``xdg-open`` bug has been fixed and a workaround has been removed (:issue:`10045`). diff --git a/src/editable_line.rs b/src/editable_line.rs index d2e8ad134..46539d05a 100644 --- a/src/editable_line.rs +++ b/src/editable_line.rs @@ -8,6 +8,7 @@ use crate::wchar::prelude::*; pub struct Edit { /// When undoing the edit we use this to restore the previous cursor position. pub cursor_position_before_edit: usize, + pub cursor_position_before_undo: Option, /// The span of text that is replaced by this edit. pub range: std::ops::Range, @@ -25,6 +26,7 @@ impl Edit { pub fn new(range: std::ops::Range, replacement: WString) -> Self { Self { cursor_position_before_edit: 0, + cursor_position_before_undo: None, range, old: WString::new(), replacement, @@ -224,6 +226,8 @@ impl EditableLine { pub fn undo(&mut self) -> bool { let mut did_undo = false; let mut last_group_id = None; + let position_before_undo = self.position(); + let end = self.undo_history.edits_applied; while self.undo_history.edits_applied != 0 { let edit = &self.undo_history.edits[self.undo_history.edits_applied - 1]; if did_undo @@ -247,6 +251,10 @@ impl EditableLine { self.set_position(old_position); did_undo = true; } + if did_undo { + let edit = &mut self.undo_history.edits[end - 1]; + edit.cursor_position_before_undo = Some(position_before_undo); + } self.end_edit_group(); self.undo_history.may_coalesce = false; @@ -270,7 +278,7 @@ impl EditableLine { last_group_id = edit.group_id; self.undo_history.edits_applied += 1; apply_edit(&mut self.text, &mut self.colors, edit); - self.set_position(cursor_position_after_edit(edit)); + self.set_position(edit.cursor_position_before_undo.unwrap()); did_redo = true; }