#1855: redo selects the redone cell

Undo stored the selection at the moment of undoing (wherever the user had
clicked) in the redo entry, so redo jumped back there instead of to the
cells it changed. The redo entry now keeps the undone step's selection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
justinjohn0306
2026-10-19 10:16:13 +05:30
co-authored by Claude Opus 5.5
parent 4db6876c07
commit dcd4d1d13f
2 changed files with 18 additions and 1 deletions
+2 -1
View File
@@ -601,7 +601,8 @@ fn undo(s: &mut Session, p: &Json) -> Result<Json> {
let now = d.wb.clone();
for _ in 0..steps {
let Some(e) = d.undo.pop() else { break };
let cur = crate::HistoryEntry { label: e.label.clone(), wb: d.wb.clone(), selection: d.selection.clone() };
// Redo goes back to the undone edit's cells, not wherever the user clicked before undoing (#1855).
let cur = crate::HistoryEntry { label: e.label.clone(), wb: d.wb.clone(), selection: e.selection.clone() };
d.redo.push(cur);
label = e.label.clone();
d.wb = e.wb;
+16
View File
@@ -253,6 +253,22 @@ fn undo_redo() {
assert!(s.doc().unwrap().is_dirty());
}
#[test]
fn redo_selects_the_redone_cell() {
// #1855: type into A1..A3, click A1, undo, redo: the selection follows the edit to A3.
let mut s = s();
for (cell, text) in [("A1", "first"), ("A2", "second"), ("A3", "third")] {
s.execute("selection.set", json!({"cell": cell})).unwrap();
s.execute("cell.set", json!({"cell": cell, "input": text})).unwrap();
}
s.execute("selection.set", json!({"cell": "A1"})).unwrap();
s.execute("edit.undo", json!({})).unwrap();
assert_eq!(s.doc().unwrap().selection.a1(), "A3");
s.execute("edit.redo", json!({})).unwrap();
assert_eq!(v(&s, "A3"), Value::from("third"));
assert_eq!(s.doc().unwrap().selection.a1(), "A3");
}
#[test]
fn shape_text_edit_undo_redo_and_noop() {
let mut s = s();