mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-29 13:16:50 -06:00
Engine: a group rolled back inside a command keeps the redo history
A command that changed the workbook cleared the redo history even when an open group owned its step. When the group was then rolled back inside the same command (the debugger's Stop with Undo Changes), the rollback put the redo history back and the command's bookkeeping cleared it again. Now only a command that makes a step of its own clears the redo history; a group clears it when it ends as a step, and a rollback restores it.
This commit is contained in:
@@ -469,8 +469,10 @@ impl Session {
|
||||
d.undo.truncate(len);
|
||||
}
|
||||
d.undo.push(HistoryEntry { label, wb, selection: sel });
|
||||
d.redo.clear();
|
||||
}
|
||||
d.redo.clear();
|
||||
// Inside a group the redo history waits for the group: `group_end` clears it when the
|
||||
// group becomes a step, and `group_rollback` puts it back as it was.
|
||||
d.revision += 1;
|
||||
}
|
||||
// The history limit applies once the outermost command has collapsed its steps, so the
|
||||
|
||||
@@ -226,6 +226,13 @@ fn register_group_commands() {
|
||||
});
|
||||
// A command that is one group keeps the group's name.
|
||||
register("test.onlyGroup", |s, _| s.grouped("Named Step", |s| put(s, "D1", "x")).map(|_| json!({})));
|
||||
// An edit, then the rollback of the innermost group that was open before the command.
|
||||
register("test.rollbackOpenGroup", |s, _| {
|
||||
put(s, "E1", "gone")?;
|
||||
let token = s.groups.last().map(|g| crate::GroupToken { id: g.id, doc: g.doc });
|
||||
s.group_rollback(token.ok_or_else(|| EngineError::Other("no group".into()))?)?;
|
||||
Ok(json!({}))
|
||||
});
|
||||
// An edit, then the end of the innermost group that was open before the command.
|
||||
register("test.endOpenGroup", |s, _| {
|
||||
put(s, "E1", "end")?;
|
||||
@@ -278,6 +285,25 @@ fn a_stale_group_step_does_not_name_a_later_command() {
|
||||
assert!(v(&s, "B2").is_empty() && v(&s, "D1").is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_group_rolled_back_inside_a_command_keeps_the_redo_history() {
|
||||
// The debugger's Stop with Undo Changes rolls its group back inside a command. The rollback
|
||||
// put the redo history back, and the command's own bookkeeping then cleared it again.
|
||||
register_group_commands();
|
||||
let mut s = s();
|
||||
set(&mut s, "A1", "first");
|
||||
s.execute("edit.undo", json!({})).unwrap();
|
||||
assert_eq!(s.doc().unwrap().redo.len(), 1);
|
||||
let token = s.group_begin("Debug").unwrap();
|
||||
set(&mut s, "B1", "inside");
|
||||
s.execute("test.rollbackOpenGroup", json!({})).unwrap();
|
||||
assert!(!s.in_group(token.doc));
|
||||
assert!(v(&s, "B1").is_empty() && v(&s, "E1").is_empty());
|
||||
assert_eq!(s.doc().unwrap().redo.len(), 1, "the redo history survives the rolled-back group");
|
||||
s.execute("edit.redo", json!({})).unwrap();
|
||||
assert_eq!(v(&s, "A1").display(), "first");
|
||||
}
|
||||
|
||||
/// Fills the undo history to the limit with edits of Z1 ("v0" to "v99"), and returns its snapshots.
|
||||
fn fill_history(s: &mut Session) -> Vec<std::sync::Arc<gridcraft_model::Workbook>> {
|
||||
for i in 0..crate::UNDO_LIMIT {
|
||||
|
||||
Reference in New Issue
Block a user