On redo, restore pre-undo cursor position

This commit is contained in:
Johannes Altmanninger 2024-04-03 12:05:09 +02:00
parent 3af849d739
commit af1b599818
2 changed files with 10 additions and 1 deletions

View file

@ -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`).

View file

@ -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<usize>,
/// The span of text that is replaced by this edit.
pub range: std::ops::Range<usize>,
@ -25,6 +26,7 @@ impl Edit {
pub fn new(range: std::ops::Range<usize>, 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;
}