autosave: Respect project autosave settings per file (#13369)

This fixes #13316 by checking whether there are any local workspace
settings for a given file.

Release Notes:

- Fixed `autosave` settings in project-specific settings file being
ignored. ([#13316](https://github.com/zed-industries/zed/issues/13316)).

Co-authored-by: Bennet <bennet@zed.dev>
This commit is contained in:
Thorsten Ball 2024-06-24 14:56:22 +02:00 committed by GitHub
parent 3ee3c6a3bd
commit 40748b0a15
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 38 additions and 17 deletions

View File

@ -20,7 +20,7 @@ use gpui::{
use project::{Project, ProjectEntryId, ProjectPath}; use project::{Project, ProjectEntryId, ProjectPath};
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources}; use settings::{Settings, SettingsLocation, SettingsSources};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{ use std::{
any::{Any, TypeId}, any::{Any, TypeId},
@ -331,6 +331,7 @@ pub trait ItemHandle: 'static + Send {
fn show_toolbar(&self, cx: &AppContext) -> bool; fn show_toolbar(&self, cx: &AppContext) -> bool;
fn pixel_position_of_cursor(&self, cx: &AppContext) -> Option<Point<Pixels>>; fn pixel_position_of_cursor(&self, cx: &AppContext) -> Option<Point<Pixels>>;
fn downgrade_item(&self) -> Box<dyn WeakItemHandle>; fn downgrade_item(&self) -> Box<dyn WeakItemHandle>;
fn workspace_settings<'a>(&self, cx: &'a AppContext) -> &'a WorkspaceSettings;
} }
pub trait WeakItemHandle: Send + Sync { pub trait WeakItemHandle: Send + Sync {
@ -401,6 +402,20 @@ impl<T: Item> ItemHandle for View<T> {
result result
} }
fn workspace_settings<'a>(&self, cx: &'a AppContext) -> &'a WorkspaceSettings {
if let Some(project_path) = self.project_path(cx) {
WorkspaceSettings::get(
Some(SettingsLocation {
worktree_id: project_path.worktree_id.into(),
path: &project_path.path,
}),
cx,
)
} else {
WorkspaceSettings::get_global(cx)
}
}
fn project_entry_ids(&self, cx: &AppContext) -> SmallVec<[ProjectEntryId; 3]> { fn project_entry_ids(&self, cx: &AppContext) -> SmallVec<[ProjectEntryId; 3]> {
let mut result = SmallVec::new(); let mut result = SmallVec::new();
self.read(cx).for_each_project_item(cx, &mut |_, item| { self.read(cx).for_each_project_item(cx, &mut |_, item| {
@ -567,7 +582,8 @@ impl<T: Item> ItemHandle for View<T> {
} }
ItemEvent::Edit => { ItemEvent::Edit => {
let autosave = WorkspaceSettings::get_global(cx).autosave; let autosave = item.workspace_settings(cx).autosave;
if let AutosaveSetting::AfterDelay { milliseconds } = autosave { if let AutosaveSetting::AfterDelay { milliseconds } = autosave {
let delay = Duration::from_millis(milliseconds); let delay = Duration::from_millis(milliseconds);
let item = item.clone(); let item = item.clone();
@ -584,8 +600,8 @@ impl<T: Item> ItemHandle for View<T> {
)); ));
cx.on_blur(&self.focus_handle(cx), move |workspace, cx| { cx.on_blur(&self.focus_handle(cx), move |workspace, cx| {
if WorkspaceSettings::get_global(cx).autosave == AutosaveSetting::OnFocusChange { if let Some(item) = weak_item.upgrade() {
if let Some(item) = weak_item.upgrade() { if item.workspace_settings(cx).autosave == AutosaveSetting::OnFocusChange {
Pane::autosave_item(&item, workspace.project.clone(), cx) Pane::autosave_item(&item, workspace.project.clone(), cx)
.detach_and_log_err(cx); .detach_and_log_err(cx);
} }

View File

@ -1421,7 +1421,7 @@ impl Pane {
if save_intent == SaveIntent::Close { if save_intent == SaveIntent::Close {
let will_autosave = cx.update(|cx| { let will_autosave = cx.update(|cx| {
matches!( matches!(
WorkspaceSettings::get_global(cx).autosave, item.workspace_settings(cx).autosave,
AutosaveSetting::OnFocusChange | AutosaveSetting::OnWindowChange AutosaveSetting::OnFocusChange | AutosaveSetting::OnWindowChange
) && Self::can_autosave_item(item, cx) ) && Self::can_autosave_item(item, cx)
})?; })?;
@ -1490,13 +1490,12 @@ impl Pane {
project: Model<Project>, project: Model<Project>,
cx: &mut WindowContext, cx: &mut WindowContext,
) -> Task<Result<()>> { ) -> Task<Result<()>> {
let format = if let AutosaveSetting::AfterDelay { .. } = let format =
WorkspaceSettings::get_global(cx).autosave if let AutosaveSetting::AfterDelay { .. } = item.workspace_settings(cx).autosave {
{ false
false } else {
} else { true
true };
};
if Self::can_autosave_item(item, cx) { if Self::can_autosave_item(item, cx) {
item.save(format, project, cx) item.save(format, project, cx)
} else { } else {

View File

@ -3502,11 +3502,11 @@ impl Workspace {
if let Some(item) = pane.active_item() { if let Some(item) = pane.active_item() {
item.workspace_deactivated(cx); item.workspace_deactivated(cx);
} }
if matches!( for item in pane.items() {
WorkspaceSettings::get_global(cx).autosave, if matches!(
AutosaveSetting::OnWindowChange | AutosaveSetting::OnFocusChange item.workspace_settings(cx).autosave,
) { AutosaveSetting::OnWindowChange | AutosaveSetting::OnFocusChange
for item in pane.items() { ) {
Pane::autosave_item(item.as_ref(), self.project.clone(), cx) Pane::autosave_item(item.as_ref(), self.project.clone(), cx)
.detach_and_log_err(cx); .detach_and_log_err(cx);
} }

View File

@ -70,6 +70,12 @@ pub const FS_WATCH_LATENCY: Duration = Duration::from_millis(100);
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, PartialOrd, Ord)] #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, PartialOrd, Ord)]
pub struct WorktreeId(usize); pub struct WorktreeId(usize);
impl From<WorktreeId> for usize {
fn from(value: WorktreeId) -> Self {
value.0
}
}
/// A set of local or remote files that are being opened as part of a project. /// A set of local or remote files that are being opened as part of a project.
/// Responsible for tracking related FS (for local)/collab (for remote) events and corresponding updates. /// Responsible for tracking related FS (for local)/collab (for remote) events and corresponding updates.
/// Stores git repositories data and the diagnostics for the file(s). /// Stores git repositories data and the diagnostics for the file(s).