engine: restore tabs closed inside a failed command group

This commit is contained in:
Logan Jennings
2026-10-22 07:24:22 -07:00
parent 9ec80bf2c2
commit ef4aecfd17
2 changed files with 32 additions and 1 deletions
+22
View File
@@ -34,6 +34,28 @@ fn failed_group_closes_documents_opened_inside_it() {
assert_eq!(s.journal, before_journal);
}
#[test]
fn failed_group_reopens_documents_closed_inside_it() {
let mut s = Session::new();
s.execute("file.new", &json!({"name": "Second"})).unwrap();
assert_eq!((s.docs.len(), s.active), (2, 1));
let result = s.execute(
"command.batch",
&json!({
"commands": [
{"command": "file.close", "params": {"index": 1, "force": true}},
{"command": "node.set", "params": {"id": 999999, "props": {"name": "must fail"}}}
]
}),
);
assert!(result.is_err());
assert_eq!(s.docs.len(), 2);
assert_eq!(s.active, 1);
assert!(s.ds().is_ok());
}
#[test]
fn failed_plugin_run_restores_each_document_without_restoring_unrelated_state() {
let mut s = Session::new();
+10 -1
View File
@@ -1277,6 +1277,8 @@ impl Session {
self.docs.iter().map(|ds| (ds.uid, ds.doc.clone(), ds.selection.clone(), ds.page, ds.history.undo.len(), ds.history.limit)).collect();
// An edit inside clears the redo steps; a failed group has to bring them back.
let redo_before: Vec<_> = self.docs.iter().map(|ds| ds.history.redo.clone()).collect();
// Tabs the group closes (or reorders) come back from this.
let tabs_before = self.docs.clone();
let active = self.active;
let journal_len = self.journal.len();
@@ -1293,7 +1295,14 @@ impl Session {
}
if result.is_err() {
self.docs.retain(|ds| before.iter().any(|(uid, _, _, _, _, _)| *uid == ds.uid));
let mut current = std::mem::take(&mut self.docs);
self.docs = tabs_before
.into_iter()
.map(|t| match current.iter().position(|d| d.uid == t.uid) {
Some(i) => current.swap_remove(i),
None => t,
})
.collect();
for ((uid, doc, selection, page, undo_len, limit), redo) in before.iter().zip(redo_before) {
if let Some(ds) = self.docs.iter_mut().find(|ds| ds.uid == *uid) {
ds.history.redo = redo;