Recall empty, unsaved buffers on app load (#33475)
Closes #33342 This PR implements serialization of pinned tabs regardless of their state (empty, untitled, etc.) The root cause was that empty untitled tabs were being skipped during serialization but their pinned state was still being persisted, leading to a mismatch between the stored pinned count and actual restorable tabs, this issue lead to a crash which was patched by @JosephTLyons, but this PR aims to be a proper fix. **Note**: I'm still evaluating the best approach for this fix. Currently exploring whether it's necessary to store the pinned state in the database schema or if there's a simpler solution that doesn't require schema changes. --- **Edit from Joseph** We ended up going with altering our recall logic, where we always restore all editors, even those that are new, empty, and unsaved. This prevents the crash that #33335 patched because we are no longer skipping the restoration of pinned editors that have no text and haven't been saved, throwing off the count dealing with the number of pinned items. This solution is rather simple, but I think it's fine. We simply just restore everything the same, no conditional dropping of anything. This is also consistent with VS Code, which also restores all editors, regardless of whether or not a new, unsaved buffers have content or not. https://github.com/zed-industries/zed/tree/alt-solution-for-%2333342 Release Notes: - N/A --------- Co-authored-by: Joseph T. Lyons <JosephTLyons@gmail.com>
This commit is contained in:
parent
67c765a99a
commit
12bc8907d9
1 changed files with 47 additions and 1 deletions
|
@ -1226,7 +1226,20 @@ impl SerializableItem for Editor {
|
|||
abs_path: None,
|
||||
contents: None,
|
||||
..
|
||||
} => Task::ready(Err(anyhow!("No path or contents found for buffer"))),
|
||||
} => window.spawn(cx, async move |cx| {
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| project.create_buffer(cx))?
|
||||
.await?;
|
||||
|
||||
cx.update(|window, cx| {
|
||||
cx.new(|cx| {
|
||||
let mut editor = Editor::for_buffer(buffer, Some(project), window, cx);
|
||||
|
||||
editor.read_metadata_from_db(item_id, workspace_id, window, cx);
|
||||
editor
|
||||
})
|
||||
})
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2098,5 +2111,38 @@ mod tests {
|
|||
assert!(editor.has_conflict(cx)); // The editor should have a conflict
|
||||
});
|
||||
}
|
||||
|
||||
// Test case 5: Deserialize with no path, no content, no language, and no old mtime (new, empty, unsaved buffer)
|
||||
{
|
||||
let project = Project::test(fs.clone(), [path!("/file.rs").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
|
||||
let workspace_id = workspace::WORKSPACE_DB.next_id().await.unwrap();
|
||||
|
||||
let item_id = 10000 as ItemId;
|
||||
let serialized_editor = SerializedEditor {
|
||||
abs_path: None,
|
||||
contents: None,
|
||||
language: None,
|
||||
mtime: None,
|
||||
};
|
||||
|
||||
DB.save_serialized_editor(item_id, workspace_id, serialized_editor)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let deserialized =
|
||||
deserialize_editor(item_id, workspace_id, workspace, project, cx).await;
|
||||
|
||||
deserialized.update(cx, |editor, cx| {
|
||||
assert_eq!(editor.text(cx), "");
|
||||
assert!(!editor.is_dirty(cx));
|
||||
assert!(!editor.has_conflict(cx));
|
||||
|
||||
let buffer = editor.buffer().read(cx).as_singleton().unwrap().read(cx);
|
||||
assert!(buffer.file().is_none());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue