Workspace

Conrad Irwin created

Change summary

crates/project/src/context_server_store.rs        |  2 
crates/project/src/project_settings.rs            |  1 
crates/settings/src/settings_content.rs           | 33 ++++----
crates/settings/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(-)

Detailed changes

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
         {

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

crates/settings/src/settings_content.rs 🔗

@@ -28,7 +28,7 @@ pub struct SettingsContent {
     pub project: ProjectSettingsContent,
 
     #[serde(flatten)]
-    pub theme: ThemeSettingsContent,
+    pub theme: Box<ThemeSettingsContent>,
 
     #[serde(flatten)]
     pub extension: ExtensionSettingsContent,
@@ -37,6 +37,7 @@ pub struct SettingsContent {
     pub workspace: WorkspaceSettingsContent,
 
     pub tabs: Option<ItemSettingsContent>,
+    pub tab_bar: Option<TabBarSettingsContent>,
 
     pub preview_tabs: Option<PreviewTabsSettingsContent>,
 
@@ -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<SettingsContent>,
 
-    pub dev: Option<SettingsContent>,
-    pub nightly: Option<SettingsContent>,
-    pub preview: Option<SettingsContent>,
-    pub stable: Option<SettingsContent>,
+    pub dev: Option<Box<SettingsContent>>,
+    pub nightly: Option<Box<SettingsContent>>,
+    pub preview: Option<Box<SettingsContent>>,
+    pub stable: Option<Box<SettingsContent>>,
 
-    pub macos: Option<SettingsContent>,
-    pub windows: Option<SettingsContent>,
-    pub linux: Option<SettingsContent>,
+    pub macos: Option<Box<SettingsContent>>,
+    pub windows: Option<Box<SettingsContent>>,
+    pub linux: Option<Box<SettingsContent>>,
 
     #[serde(default)]
     pub profiles: HashMap<String, SettingsContent>,
@@ -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,
         }
     }

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<DockPosition>,
+    pub resize_all_panels_in_dock: Option<Vec<DockPosition>>,
     /// 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<bool>,
-
-    // Settings related to the editor's tab bar.
-    pub tab_bar: Option<TabBarSettingsContent>,
-
-    pub tabs: Option<ItemSettingsContent>,
 }
 
 #[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]

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<TypeId, Box<dyn AnySettingValue>>,
-    default_settings: SettingsContent,
+    default_settings: Box<SettingsContent>,
     user_settings: Option<UserSettingsContent>,
-    global_settings: Option<SettingsContent>,
+    global_settings: Option<Box<SettingsContent>>,
 
-    extension_settings: Option<SettingsContent>,
-    server_settings: Option<SettingsContent>,
+    extension_settings: Option<Box<SettingsContent>>,
+    server_settings: Option<Box<SettingsContent>>,
     local_settings: BTreeMap<(WorktreeId, Arc<Path>), SettingsContent>,
     raw_editorconfig_settings: BTreeMap<(WorktreeId, Arc<Path>), (String, Option<Editorconfig>)>,
 
@@ -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"  }

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<settings::DockPosition> for DockPosition {
     fn from(value: settings::DockPosition) -> Self {
         match value {

crates/workspace/src/pane.rs 🔗

@@ -5819,8 +5819,7 @@ mod tests {
         init_test(cx);
         cx.update_global::<SettingsStore, ()>(|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::<SettingsStore, ()>(|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);
             });
         });

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::<WorkspaceSettings>(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::<WorkspaceSettings>(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::<WorkspaceSettings>(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::<WorkspaceSettings>(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::<WorkspaceSettings>(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::<WorkspaceSettings>(cx, |settings| {
-                settings.close_on_file_delete = Some(true);
+            store.update_user_settings(cx, |settings| {
+                settings.workspace.close_on_file_delete = Some(true);
             });
         });
 

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<NonZeroUsize>,
     pub when_closing_with_no_tabs: settings::CloseWindowWhenNoItems,
     pub on_last_window_closed: settings::OnLastWindowClosed,
-    pub resize_all_panels_in_dock: Vec<DockPosition>, // <- This one is not an overwrite merge, it is an extend merge
+    pub resize_all_panels_in_dock: Vec<DockPosition>,
     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::<DockPosition>::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)
         }
     }
 }