From 8195364b36d2ba8c5a337c85d89449f858567915 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Tue, 16 Sep 2025 22:59:22 -0600 Subject: [PATCH] Workspace --- crates/project/src/context_server_store.rs | 2 - crates/project/src/project_settings.rs | 1 - crates/settings/src/settings_content.rs | 33 ++++----- .../src/settings_content/workspace.rs | 8 +-- crates/settings/src/settings_store.rs | 33 +++++---- crates/workspace/src/dock.rs | 8 ++- crates/workspace/src/pane.rs | 5 +- crates/workspace/src/workspace.rs | 33 ++++----- crates/workspace/src/workspace_settings.rs | 68 ++++++++++--------- 9 files changed, 95 insertions(+), 96 deletions(-) diff --git a/crates/project/src/context_server_store.rs b/crates/project/src/context_server_store.rs index 40a14ed37b6db3e5f25dfc5e6926f7a38bc2b510..9444d51581fe4116fd06692a977ace6ce052ebdd 100644 --- a/crates/project/src/context_server_store.rs +++ b/crates/project/src/context_server_store.rs @@ -1027,7 +1027,6 @@ mod tests { cx.run_until_parked(); } - dbg!("hi"); // Ensure that mcp-2 is removed once it is removed from the settings { @@ -1055,7 +1054,6 @@ mod tests { assert_eq!(store.read(cx).status_for_server(&server_2_id), None); }); } - dbg!("bye"); // Ensure that nothing happens if the settings do not change { diff --git a/crates/project/src/project_settings.rs b/crates/project/src/project_settings.rs index 192728ac66af21b02c8562b2f14a4a0f8b484364..3b88261e8122fabb9c56118b21482c78ebb63873 100644 --- a/crates/project/src/project_settings.rs +++ b/crates/project/src/project_settings.rs @@ -542,7 +542,6 @@ impl Settings for ProjectSettings { .into_iter() .map(|(key, value)| (key, value.into())), ); - dbg!(&self.context_servers); self.dap.extend( project .dap diff --git a/crates/settings/src/settings_content.rs b/crates/settings/src/settings_content.rs index 6e128e50b52958e8e24feb699ee9541782556574..432dbb2f8bf4b713a3d74a4c2fb21ff8797bd4c2 100644 --- a/crates/settings/src/settings_content.rs +++ b/crates/settings/src/settings_content.rs @@ -28,7 +28,7 @@ pub struct SettingsContent { pub project: ProjectSettingsContent, #[serde(flatten)] - pub theme: ThemeSettingsContent, + pub theme: Box, #[serde(flatten)] pub extension: ExtensionSettingsContent, @@ -37,6 +37,7 @@ pub struct SettingsContent { pub workspace: WorkspaceSettingsContent, pub tabs: Option, + pub tab_bar: Option, pub preview_tabs: Option, @@ -119,16 +120,16 @@ pub struct ServerSettingsContent { #[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize, JsonSchema)] pub struct UserSettingsContent { #[serde(flatten)] - pub content: SettingsContent, + pub content: Box, - pub dev: Option, - pub nightly: Option, - pub preview: Option, - pub stable: Option, + pub dev: Option>, + pub nightly: Option>, + pub preview: Option>, + pub stable: Option>, - pub macos: Option, - pub windows: Option, - pub linux: Option, + pub macos: Option>, + pub windows: Option>, + pub linux: Option>, #[serde(default)] pub profiles: HashMap, @@ -141,18 +142,18 @@ pub struct ExtensionsSettingsContent { impl UserSettingsContent { pub fn for_release_channel(&self) -> Option<&SettingsContent> { match *release_channel::RELEASE_CHANNEL { - ReleaseChannel::Dev => self.dev.as_ref(), - ReleaseChannel::Nightly => self.nightly.as_ref(), - ReleaseChannel::Preview => self.preview.as_ref(), - ReleaseChannel::Stable => self.stable.as_ref(), + ReleaseChannel::Dev => self.dev.as_deref(), + ReleaseChannel::Nightly => self.nightly.as_deref(), + ReleaseChannel::Preview => self.preview.as_deref(), + ReleaseChannel::Stable => self.stable.as_deref(), } } pub fn for_os(&self) -> Option<&SettingsContent> { match env::consts::OS { - "macos" => self.macos.as_ref(), - "linux" => self.linux.as_ref(), - "windows" => self.windows.as_ref(), + "macos" => self.macos.as_deref(), + "linux" => self.linux.as_deref(), + "windows" => self.windows.as_deref(), _ => None, } } diff --git a/crates/settings/src/settings_content/workspace.rs b/crates/settings/src/settings_content/workspace.rs index 24a7b9a2be624ff48c200893c878dbff9b66b3c6..a5fe638df3c60380abc761b51f9976d6aa82d8a3 100644 --- a/crates/settings/src/settings_content/workspace.rs +++ b/crates/settings/src/settings_content/workspace.rs @@ -88,8 +88,7 @@ pub struct WorkspaceSettingsContent { /// Whether to resize all the panels in a dock when resizing the dock. /// /// Default: ["left"] - #[serde(default)] - pub resize_all_panels_in_dock: Vec, + pub resize_all_panels_in_dock: Option>, /// Whether to automatically close files that have been deleted on disk. /// /// Default: false @@ -104,11 +103,6 @@ pub struct WorkspaceSettingsContent { /// /// Default: true pub zoomed_padding: Option, - - // Settings related to the editor's tab bar. - pub tab_bar: Option, - - pub tabs: Option, } #[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, JsonSchema)] diff --git a/crates/settings/src/settings_store.rs b/crates/settings/src/settings_store.rs index 7f6d332c4f6e5084c759dd475886fe454f2375a6..4bcb984f87bd62d7f6ab7e89d272651035cce20e 100644 --- a/crates/settings/src/settings_store.rs +++ b/crates/settings/src/settings_store.rs @@ -140,12 +140,12 @@ pub struct SettingsLocation<'a> { /// A set of strongly-typed setting values defined via multiple config files. pub struct SettingsStore { setting_values: HashMap>, - default_settings: SettingsContent, + default_settings: Box, user_settings: Option, - global_settings: Option, + global_settings: Option>, - extension_settings: Option, - server_settings: Option, + extension_settings: Option>, + server_settings: Option>, local_settings: BTreeMap<(WorktreeId, Arc), SettingsContent>, raw_editorconfig_settings: BTreeMap<(WorktreeId, Arc), (String, Option)>, @@ -260,11 +260,11 @@ impl SettingsStore { let mut refinements = Vec::default(); - if let Some(extension_settings) = self.extension_settings.as_ref() { + if let Some(extension_settings) = self.extension_settings.as_deref() { refinements.push(extension_settings) } - if let Some(global_settings) = self.global_settings.as_ref() { + if let Some(global_settings) = self.global_settings.as_deref() { refinements.push(global_settings) } @@ -619,7 +619,7 @@ impl SettingsStore { parse_json_with_comments(global_settings_content)? }; - self.global_settings = Some(settings); + self.global_settings = Some(Box::new(settings)); self.recompute_values(None, cx)?; Ok(()) } @@ -636,9 +636,11 @@ impl SettingsStore { }; // Rewrite the server settings into a content type - self.server_settings = settings.map(|settings| SettingsContent { - project: settings.project, - ..Default::default() + self.server_settings = settings.map(|settings| { + Box::new(SettingsContent { + project: settings.project, + ..Default::default() + }) }); self.recompute_values(None, cx)?; @@ -762,13 +764,13 @@ impl SettingsStore { content: ExtensionsSettingsContent, cx: &mut App, ) -> Result<()> { - self.extension_settings = Some(SettingsContent { + self.extension_settings = Some(Box::new(SettingsContent { project: ProjectSettingsContent { all_languages: content.all_languages, ..Default::default() }, ..Default::default() - }); + })); self.recompute_values(None, cx)?; Ok(()) } @@ -839,11 +841,11 @@ impl SettingsStore { let mut refinements = Vec::default(); - if let Some(extension_settings) = self.extension_settings.as_ref() { + if let Some(extension_settings) = self.extension_settings.as_deref() { refinements.push(extension_settings) } - if let Some(global_settings) = self.global_settings.as_ref() { + if let Some(global_settings) = self.global_settings.as_deref() { refinements.push(global_settings) } @@ -1286,7 +1288,6 @@ mod tests { ) { store.set_user_settings(&old_json, cx).ok(); let edits = store.edits_for_update(&old_json, update); - dbg!(&edits); let mut new_json = old_json; for (range, replacement) in edits.into_iter() { new_json.replace_range(range, &replacement); @@ -1401,9 +1402,7 @@ mod tests { }"# .unindent(), |settings| { - dbg!(&settings.title_bar); settings.title_bar.as_mut().unwrap().show = Some(TitleBarVisibilityContent::Never); - dbg!(&settings.title_bar); }, r#"{ "title_bar": { "show": "never", "name": "Max" } diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index 77ea068a147e0d3c69efdeace3fb6541cfab25dd..09fa6f068f92dda29beac98eff0dcf41e93dc1bf 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -9,7 +9,6 @@ use gpui::{ Render, SharedString, StyleRefinement, Styled, Subscription, WeakEntity, Window, deferred, div, px, }; -pub use settings::DockPosition; use settings::SettingsStore; use std::sync::Arc; use ui::{ContextMenu, Divider, DividerColor, IconButton, Tooltip, h_flex}; @@ -209,6 +208,13 @@ impl Focusable for Dock { } } +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum DockPosition { + Left, + Bottom, + Right, +} + impl From for DockPosition { fn from(value: settings::DockPosition) -> Self { match value { diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 37706cc3985612777e26ac0d12e08cfbb4fb9b83..04898de15e6245ea4a9a0e270ea0f7391109017e 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -5819,8 +5819,7 @@ mod tests { init_test(cx); cx.update_global::(|s, cx| { s.update_user_settings(cx, |s| { - s.workspace.tabs.get_or_insert_default().activate_on_close = - Some(ActivateOnClose::Neighbour); + s.tabs.get_or_insert_default().activate_on_close = Some(ActivateOnClose::Neighbour); }); }); let fs = FakeFs::new(cx.executor()); @@ -5909,7 +5908,7 @@ mod tests { init_test(cx); cx.update_global::(|s, cx| { s.update_user_settings(cx, |s| { - s.workspace.tabs.get_or_insert_default().activate_on_close = + s.tabs.get_or_insert_default().activate_on_close = Some(ActivateOnClose::LeftNeighbour); }); }); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 11425472a20ef8ac3f4639942be1f4f35ec88e47..f4d54b82aee9966b5b593f29e9d488e90863179b 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -52,10 +52,7 @@ pub use item::{ ProjectItem, SerializableItem, SerializableItemHandle, WeakItemHandle, }; use itertools::Itertools; -use language::{ - Buffer, LanguageRegistry, Rope, - language_settings::{AllLanguageSettings, all_language_settings}, -}; +use language::{Buffer, LanguageRegistry, Rope, language_settings::all_language_settings}; pub use modal_layer::*; use node_runtime::NodeRuntime; use notifications::{ @@ -8698,13 +8695,12 @@ mod tests { item.update_in(cx, |item, window, cx| { cx.focus_self(window); SettingsStore::update_global(cx, |settings, cx| { - settings.update_user_settings::(cx, |settings| { - settings.autosave = Some(AutosaveSetting::OnFocusChange); + settings.update_user_settings(cx, |settings| { + settings.workspace.autosave = Some(AutosaveSetting::OnFocusChange); }) }); item.is_dirty = true; }); - // Blurring the item saves the file. item.update_in(cx, |_, window, _| window.blur()); cx.executor().run_until_parked(); @@ -8721,8 +8717,9 @@ mod tests { // Autosave after delay. item.update(cx, |item, cx| { SettingsStore::update_global(cx, |settings, cx| { - settings.update_user_settings::(cx, |settings| { - settings.autosave = Some(AutosaveSetting::AfterDelay { milliseconds: 500 }); + settings.update_user_settings(cx, |settings| { + settings.workspace.autosave = + Some(AutosaveSetting::AfterDelay { milliseconds: 500 }); }) }); item.is_dirty = true; @@ -8740,8 +8737,8 @@ mod tests { // Autosave on focus change, ensuring closing the tab counts as such. item.update(cx, |item, cx| { SettingsStore::update_global(cx, |settings, cx| { - settings.update_user_settings::(cx, |settings| { - settings.autosave = Some(AutosaveSetting::OnFocusChange); + settings.update_user_settings(cx, |settings| { + settings.workspace.autosave = Some(AutosaveSetting::OnFocusChange); }) }); item.is_dirty = true; @@ -9744,8 +9741,8 @@ mod tests { // Enable the close_on_disk_deletion setting cx.update_global(|store: &mut SettingsStore, cx| { - store.update_user_settings::(cx, |settings| { - settings.close_on_file_delete = Some(true); + store.update_user_settings(cx, |settings| { + settings.workspace.close_on_file_delete = Some(true); }); }); @@ -9812,8 +9809,8 @@ mod tests { // Ensure close_on_disk_deletion is disabled (default) cx.update_global(|store: &mut SettingsStore, cx| { - store.update_user_settings::(cx, |settings| { - settings.close_on_file_delete = Some(false); + store.update_user_settings(cx, |settings| { + settings.workspace.close_on_file_delete = Some(false); }); }); @@ -9890,7 +9887,7 @@ mod tests { // Enable the close_on_file_delete setting cx.update_global(|store: &mut SettingsStore, cx| { store.update_user_settings(cx, |settings| { - settings.tabs.get_or_insert_default().close_on_file_delete = Some(true); + settings.workspace.close_on_file_delete = Some(true); }); }); @@ -9962,8 +9959,8 @@ mod tests { // Enable the close_on_file_delete setting cx.update_global(|store: &mut SettingsStore, cx| { - store.update_user_settings::(cx, |settings| { - settings.close_on_file_delete = Some(true); + store.update_user_settings(cx, |settings| { + settings.workspace.close_on_file_delete = Some(true); }); }); diff --git a/crates/workspace/src/workspace_settings.rs b/crates/workspace/src/workspace_settings.rs index 0f56bea96650a645160b46d27a3fb2bed88e7a57..165ec776febc939997d878fc69dfd6af4043d9ad 100644 --- a/crates/workspace/src/workspace_settings.rs +++ b/crates/workspace/src/workspace_settings.rs @@ -1,7 +1,6 @@ use std::num::NonZeroUsize; use crate::DockPosition; -use anyhow::Result; use collections::HashMap; use gpui::App; use serde::Deserialize; @@ -18,7 +17,7 @@ pub struct WorkspaceSettings { pub bottom_dock_layout: settings::BottomDockLayout, pub pane_split_direction_horizontal: settings::PaneSplitDirectionHorizontal, pub pane_split_direction_vertical: settings::PaneSplitDirectionVertical, - pub centered_layout: settings::CenteredLayoutSettings, // <- This one is hard to describe, especially as it has + pub centered_layout: settings::CenteredLayoutSettings, pub confirm_quit: bool, pub show_call_status_icon: bool, pub autosave: AutosaveSetting, @@ -31,26 +30,12 @@ pub struct WorkspaceSettings { pub max_tabs: Option, pub when_closing_with_no_tabs: settings::CloseWindowWhenNoItems, pub on_last_window_closed: settings::OnLastWindowClosed, - pub resize_all_panels_in_dock: Vec, // <- This one is not an overwrite merge, it is an extend merge + pub resize_all_panels_in_dock: Vec, pub close_on_file_delete: bool, pub use_system_window_tabs: bool, pub zoomed_padding: bool, } -#[derive(Copy, Clone, Debug, PartialEq)] -pub struct CenteredLayoutSettings { - /// The relative width of the left padding of the central pane from the - /// workspace when the centered layout is used. - /// - /// Default: 0.2 - pub left_padding: f32, - // The relative width of the right padding of the central pane from the - // workspace when the centered layout is used. - /// - /// Default: 0.2 - pub right_padding: f32, -} - #[derive(Copy, Clone, PartialEq, Debug, Default)] pub struct ActivePanelModifiers { /// Size of the border surrounding the active pane. @@ -78,7 +63,7 @@ pub struct TabBarSettings { } impl Settings for WorkspaceSettings { - fn from_defaults(content: &settings::SettingsContent, cx: &mut App) -> Self { + fn from_defaults(content: &settings::SettingsContent, _cx: &mut App) -> Self { let workspace = &content.workspace; Self { active_pane_modifiers: ActivePanelModifiers { @@ -116,14 +101,20 @@ impl Settings for WorkspaceSettings { max_tabs: workspace.max_tabs.clone(), when_closing_with_no_tabs: workspace.when_closing_with_no_tabs.clone().unwrap(), on_last_window_closed: workspace.on_last_window_closed.clone().unwrap(), - resize_all_panels_in_dock: workspace.resize_all_panels_in_dock.iter().collect(), + resize_all_panels_in_dock: workspace + .resize_all_panels_in_dock + .clone() + .unwrap() + .into_iter() + .map(Into::into) + .collect(), close_on_file_delete: workspace.close_on_file_delete.clone().unwrap(), use_system_window_tabs: workspace.use_system_window_tabs.clone().unwrap(), zoomed_padding: workspace.zoomed_padding.clone().unwrap(), } } - fn refine(&mut self, content: &settings::SettingsContent, cx: &mut App) { + fn refine(&mut self, content: &settings::SettingsContent, _cx: &mut App) { let workspace = &content.workspace; if let Some(border_size) = *&workspace .active_pane_modifiers @@ -169,12 +160,11 @@ impl Settings for WorkspaceSettings { .merge_from(&workspace.when_closing_with_no_tabs); self.on_last_window_closed .merge_from(&workspace.on_last_window_closed); - self.resize_all_panels_in_dock.extend( - workspace + self.resize_all_panels_in_dock.merge_from( + &workspace .resize_all_panels_in_dock - .iter() - .copied() - .map(Into::::into), + .as_ref() + .map(|resize| resize.clone().into_iter().map(Into::into).collect()), ); self.close_on_file_delete .merge_from(&workspace.close_on_file_delete); @@ -270,6 +260,26 @@ impl Settings for WorkspaceSettings { } impl Settings for TabBarSettings { + fn from_defaults(content: &settings::SettingsContent, _cx: &mut App) -> Self { + let tab_bar = content.tab_bar.clone().unwrap(); + TabBarSettings { + show: tab_bar.show.unwrap(), + show_nav_history_buttons: tab_bar.show_nav_history_buttons.unwrap(), + show_tab_bar_buttons: tab_bar.show_tab_bar_buttons.unwrap(), + } + } + + fn refine(&mut self, content: &settings::SettingsContent, _cx: &mut App) { + let Some(tab_bar) = &content.tab_bar else { + return; + }; + self.show.merge_from(&tab_bar.show); + self.show_nav_history_buttons + .merge_from(&tab_bar.show_nav_history_buttons); + self.show_tab_bar_buttons + .merge_from(&tab_bar.show_tab_bar_buttons); + } + fn import_from_vscode( vscode: &settings::VsCodeSettings, current: &mut settings::SettingsContent, @@ -279,14 +289,10 @@ impl Settings for TabBarSettings { "single" | "none" => Some(false), _ => None, }) { - current.workspace.tab_bar.get_or_insert_default().show = Some(b); + current.tab_bar.get_or_insert_default().show = Some(b); } if Some("hidden") == vscode.read_string("workbench.editor.editorActionsLocation") { - current - .workspace - .tab_bar - .get_or_insert_default() - .show_tab_bar_buttons = Some(false) + current.tab_bar.get_or_insert_default().show_tab_bar_buttons = Some(false) } } }