Fix item closing overly triggering save dialogues (#21374)

Closes https://github.com/zed-industries/zed/issues/12029

Allows to introspect project items inside items more deeply, checking
them for being dirty.
For that:
* renames `project::Item` into `project::ProjectItem`
* adds an `is_dirty(&self) -> bool` method to the renamed trait
* changes the closing logic to only care about dirty project items when
checking for save prompts conditions
* save prompts are raised only if the item is singleton without a
project path; or if the item has dirty project items that are not open
elsewhere

Release Notes:

- Fixed item closing overly triggering save dialogues
This commit is contained in:
Kirill Bulatov 2024-12-01 01:48:31 +02:00 committed by GitHub
parent c2cd84a749
commit 28849dd2a8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 600 additions and 85 deletions

View file

@ -158,16 +158,6 @@ impl NotebookEditor {
})
}
fn is_dirty(&self, cx: &AppContext) -> bool {
self.cell_map.values().any(|cell| {
if let Cell::Code(code_cell) = cell {
code_cell.read(cx).is_dirty(cx)
} else {
false
}
})
}
fn clear_outputs(&mut self, cx: &mut ViewContext<Self>) {
for cell in self.cell_map.values() {
if let Cell::Code(code_cell) = cell {
@ -500,7 +490,7 @@ pub struct NotebookItem {
id: ProjectEntryId,
}
impl project::Item for NotebookItem {
impl project::ProjectItem for NotebookItem {
fn try_open(
project: &Model<Project>,
path: &ProjectPath,
@ -561,6 +551,10 @@ impl project::Item for NotebookItem {
fn project_path(&self, _: &AppContext) -> Option<ProjectPath> {
Some(self.project_path.clone())
}
fn is_dirty(&self) -> bool {
false
}
}
impl NotebookItem {
@ -656,7 +650,7 @@ impl Item for NotebookEditor {
fn for_each_project_item(
&self,
cx: &AppContext,
f: &mut dyn FnMut(gpui::EntityId, &dyn project::Item),
f: &mut dyn FnMut(gpui::EntityId, &dyn project::ProjectItem),
) {
f(self.notebook_item.entity_id(), self.notebook_item.read(cx))
}
@ -734,8 +728,13 @@ impl Item for NotebookEditor {
}
fn is_dirty(&self, cx: &AppContext) -> bool {
// self.is_dirty(cx) TODO
false
self.cell_map.values().any(|cell| {
if let Cell::Code(code_cell) = cell {
code_cell.read(cx).is_dirty(cx)
} else {
false
}
})
}
}