Autosave files on close, when setting is afterDelay (#36929)

Closes https://github.com/zed-industries/zed/issues/12149
Closes #35524

Release Notes:

- Improved autosave behavior, to prevent a confirmation dialog when
quickly closing files and using the `afterDelay` setting

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
This commit is contained in:
itsaphel
2025-09-17 13:08:29 +00:00
committed by GitHub
co-authored by MrSubidubi
parent 86834887da
commit c54e294965
5 changed files with 49 additions and 14 deletions
+1 -7
View File
@@ -1071,18 +1071,12 @@ impl ProjectSearchView {
window: &mut Window,
cx: &mut Context<Self>,
) -> Task<anyhow::Result<()>> {
use workspace::AutosaveSetting;
let project = self.entity.read(cx).project.clone();
let can_autosave = self.results_editor.can_autosave(cx);
let autosave_setting = self.results_editor.workspace_settings(cx).autosave;
let will_autosave = can_autosave
&& matches!(
autosave_setting,
AutosaveSetting::OnFocusChange | AutosaveSetting::OnWindowChange
);
let will_autosave = can_autosave && autosave_setting.should_save_on_close();
let is_dirty = self.is_dirty(cx);
+2 -4
View File
@@ -2082,10 +2082,8 @@ impl Pane {
} else if is_dirty && (can_save || can_save_as) {
if save_intent == SaveIntent::Close {
let will_autosave = cx.update(|_window, cx| {
matches!(
item.workspace_settings(cx).autosave,
AutosaveSetting::OnFocusChange | AutosaveSetting::OnWindowChange
) && item.can_autosave(cx)
item.can_autosave(cx)
&& item.workspace_settings(cx).autosave.should_save_on_close()
})?;
if !will_autosave {
let item_id = item.item_id();
+33 -3
View File
@@ -8737,6 +8737,36 @@ mod tests {
cx.executor().advance_clock(Duration::from_millis(250));
item.read_with(cx, |item, _| assert_eq!(item.save_count, 4));
// Autosave after delay, should save earlier than delay if tab is closed
item.update(cx, |item, cx| {
item.is_dirty = true;
cx.emit(ItemEvent::Edit);
});
cx.executor().advance_clock(Duration::from_millis(250));
item.read_with(cx, |item, _| assert_eq!(item.save_count, 4));
// // Ensure auto save with delay saves the item on close, even if the timer hasn't yet run out.
pane.update_in(cx, |pane, window, cx| {
pane.close_items(window, cx, SaveIntent::Close, move |id| id == item_id)
})
.await
.unwrap();
assert!(!cx.has_pending_prompt());
item.read_with(cx, |item, _| assert_eq!(item.save_count, 5));
// Add the item again, ensuring autosave is prevented if the underlying file has been deleted.
workspace.update_in(cx, |workspace, window, cx| {
workspace.add_item_to_active_pane(Box::new(item.clone()), None, true, window, cx);
});
item.update_in(cx, |item, _window, cx| {
item.is_dirty = true;
for project_item in &mut item.project_items {
project_item.update(cx, |project_item, _| project_item.is_dirty = true);
}
});
cx.run_until_parked();
item.read_with(cx, |item, _| assert_eq!(item.save_count, 5));
// Autosave on focus change, ensuring closing the tab counts as such.
item.update(cx, |item, cx| {
SettingsStore::update_global(cx, |settings, cx| {
@@ -8756,7 +8786,7 @@ mod tests {
.await
.unwrap();
assert!(!cx.has_pending_prompt());
item.read_with(cx, |item, _| assert_eq!(item.save_count, 5));
item.read_with(cx, |item, _| assert_eq!(item.save_count, 6));
// Add the item again, ensuring autosave is prevented if the underlying file has been deleted.
workspace.update_in(cx, |workspace, window, cx| {
@@ -8770,7 +8800,7 @@ mod tests {
window.blur();
});
cx.run_until_parked();
item.read_with(cx, |item, _| assert_eq!(item.save_count, 5));
item.read_with(cx, |item, _| assert_eq!(item.save_count, 6));
// Ensure autosave is prevented for deleted files also when closing the buffer.
let _close_items = pane.update_in(cx, |pane, window, cx| {
@@ -8778,7 +8808,7 @@ mod tests {
});
cx.run_until_parked();
assert!(cx.has_pending_prompt());
item.read_with(cx, |item, _| assert_eq!(item.save_count, 5));
item.read_with(cx, |item, _| assert_eq!(item.save_count, 6));
}
#[gpui::test]
@@ -254,6 +254,17 @@ pub enum AutosaveSetting {
OnWindowChange,
}
impl AutosaveSetting {
pub fn should_save_on_close(&self) -> bool {
matches!(
&self,
AutosaveSetting::OnFocusChange
| AutosaveSetting::OnWindowChange
| AutosaveSetting::AfterDelay { .. }
)
}
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum PaneSplitDirectionHorizontal {
+2
View File
@@ -246,6 +246,8 @@ Define extensions which should be installed (`true`) or never installed (`false`
}
```
Note that a save will be triggered when an unsaved tab is closed, even if this is earlier than the configured inactivity period.
## Autoscroll on Clicks
- Description: Whether to scroll when clicking near the edge of the visible text area.