panels

Ben Kunkle created

Change summary

crates/collab_ui/src/collab_panel.rs           |   2 
crates/collab_ui/src/notification_panel.rs     |   4 
crates/collab_ui/src/panel_settings.rs         | 128 ++++++++++---------
crates/file_finder/src/file_finder_settings.rs |  31 ----
crates/settings/src/settings_content.rs        |  81 ++++++++++++
crates/zeta/src/onboarding_modal.rs            |   6 
6 files changed, 154 insertions(+), 98 deletions(-)

Detailed changes

crates/collab_ui/src/collab_panel.rs 🔗

@@ -2996,7 +2996,7 @@ impl Panel for CollabPanel {
         settings::update_settings_file::<CollaborationPanelSettings>(
             self.fs.clone(),
             cx,
-            move |settings, _| settings.dock = Some(position),
+            move |settings, _| settings.workspace.dock = Some(position),
         );
     }
 

crates/collab_ui/src/notification_panel.rs 🔗

@@ -624,7 +624,9 @@ impl Panel for NotificationPanel {
         settings::update_settings_file::<NotificationPanelSettings>(
             self.fs.clone(),
             cx,
-            move |settings, _| settings.dock = Some(position),
+            move |settings, _| {
+                settings.notification_panel.get_or_insert_default().dock = Some(position)
+            },
         );
     }
 

crates/collab_ui/src/panel_settings.rs 🔗

@@ -1,102 +1,104 @@
 use gpui::Pixels;
-use schemars::JsonSchema;
-use serde::{Deserialize, Serialize};
-use settings::{Settings, SettingsKey, SettingsSources, SettingsUi};
+use settings::Settings;
+use ui::px;
+use util::MergeFrom as _;
 use workspace::dock::DockPosition;
 
-#[derive(Deserialize, Debug)]
+#[derive(Debug)]
 pub struct CollaborationPanelSettings {
     pub button: bool,
     pub dock: DockPosition,
     pub default_width: Pixels,
 }
 
-#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, SettingsUi, SettingsKey)]
-#[settings_key(key = "collaboration_panel")]
-pub struct PanelSettingsContent {
-    /// Whether to show the panel button in the status bar.
-    ///
-    /// Default: true
-    pub button: Option<bool>,
-    /// Where to dock the panel.
-    ///
-    /// Default: left
-    pub dock: Option<DockPosition>,
-    /// Default width of the panel in pixels.
-    ///
-    /// Default: 240
-    pub default_width: Option<f32>,
-}
-
-#[derive(Deserialize, Debug)]
+#[derive(Debug)]
 pub struct NotificationPanelSettings {
     pub button: bool,
     pub dock: DockPosition,
     pub default_width: Pixels,
 }
 
-#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, SettingsUi, SettingsKey)]
-#[settings_key(key = "notification_panel")]
-pub struct NotificationPanelSettingsContent {
-    /// Whether to show the panel button in the status bar.
-    ///
-    /// Default: true
-    pub button: Option<bool>,
-    /// Where to dock the panel.
-    ///
-    /// Default: right
-    pub dock: Option<DockPosition>,
-    /// Default width of the panel in pixels.
-    ///
-    /// Default: 300
-    pub default_width: Option<f32>,
-}
-
-#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, SettingsUi, SettingsKey)]
-#[settings_key(key = "message_editor")]
+#[derive(Clone, Default, Debug)]
 pub struct MessageEditorSettings {
     /// Whether to automatically replace emoji shortcodes with emoji characters.
     /// For example: typing `:wave:` gets replaced with `👋`.
     ///
     /// Default: false
-    pub auto_replace_emoji_shortcode: Option<bool>,
+    pub auto_replace_emoji_shortcode: bool,
 }
 
 impl Settings for CollaborationPanelSettings {
-    type FileContent = PanelSettingsContent;
+    fn from_defaults(content: &settings::SettingsContent, _cx: &mut ui::App) -> Self {
+        let panel = content.collaboration_panel.as_ref().unwrap();
+
+        Self {
+            button: panel.button.unwrap(),
+            dock: panel.dock.unwrap().into(),
+            default_width: panel.default_width.map(px).unwrap(),
+        }
+    }
 
-    fn load(
-        sources: SettingsSources<Self::FileContent>,
-        _: &mut gpui::App,
-    ) -> anyhow::Result<Self> {
-        sources.json_merge()
+    fn refine(&mut self, content: &settings::SettingsContent, _cx: &mut ui::App) {
+        if let Some(panel) = content.collaboration_panel.as_ref() {
+            self.button.merge_from(&panel.button);
+            self.default_width
+                .merge_from(&panel.default_width.map(Pixels::from));
+            self.dock.merge_from(&panel.dock.map(Into::into));
+        }
     }
 
-    fn import_from_vscode(_vscode: &settings::VsCodeSettings, _current: &mut Self::FileContent) {}
+    fn import_from_vscode(
+        _vscode: &settings::VsCodeSettings,
+        _content: &mut settings::SettingsContent,
+    ) {
+    }
 }
 
 impl Settings for NotificationPanelSettings {
-    type FileContent = NotificationPanelSettingsContent;
+    fn from_defaults(content: &settings::SettingsContent, _cx: &mut ui::App) -> Self {
+        let panel = content.notification_panel.as_ref().unwrap();
+        return Self {
+            button: panel.button.unwrap(),
+            dock: panel.dock.unwrap().into(),
+            default_width: panel.default_width.map(px).unwrap(),
+        };
+    }
 
-    fn load(
-        sources: SettingsSources<Self::FileContent>,
-        _: &mut gpui::App,
-    ) -> anyhow::Result<Self> {
-        sources.json_merge()
+    fn refine(&mut self, content: &settings::SettingsContent, _cx: &mut ui::App) {
+        let Some(panel) = content.notification_panel.as_ref() else {
+            return;
+        };
+        self.button.merge_from(&panel.button);
+        self.dock.merge_from(&panel.dock.map(Into::into));
+        self.default_width.merge_from(&panel.default_width.map(px));
     }
 
-    fn import_from_vscode(_vscode: &settings::VsCodeSettings, _current: &mut Self::FileContent) {}
+    fn import_from_vscode(
+        _vscode: &settings::VsCodeSettings,
+        _current: &mut settings::SettingsContent,
+    ) {
+    }
 }
 
 impl Settings for MessageEditorSettings {
-    type FileContent = MessageEditorSettings;
+    fn from_defaults(content: &settings::SettingsContent, _cx: &mut ui::App) -> Self {
+        let messages = content.message_editor.as_ref().unwrap();
+        Self {
+            auto_replace_emoji_shortcode: messages.auto_replace_emoji_shortcode.unwrap(),
+        }
+    }
 
-    fn load(
-        sources: SettingsSources<Self::FileContent>,
-        _: &mut gpui::App,
-    ) -> anyhow::Result<Self> {
-        sources.json_merge()
+    fn refine(&mut self, content: &settings::SettingsContent, _cx: &mut ui::App) {
+        let Some(messages) = content.message_editor.as_ref() else {
+            return;
+        };
+        self.auto_replace_emoji_shortcode
+            .merge_from(&messages.auto_replace_emoji_shortcode);
     }
 
-    fn import_from_vscode(_vscode: &settings::VsCodeSettings, _current: &mut Self::FileContent) {}
+    fn import_from_vscode(
+        _vscode: &settings::VsCodeSettings,
+        _current: &mut settings::SettingsContent,
+    ) {
+    }
 }

crates/file_finder/src/file_finder_settings.rs 🔗

@@ -11,37 +11,6 @@ pub struct FileFinderSettings {
     pub include_ignored: Option<bool>,
 }
 
-#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, SettingsUi, SettingsKey)]
-#[settings_key(key = "file_finder")]
-pub struct FileFinderSettingsContent {
-    /// Whether to show file icons in the file finder.
-    ///
-    /// Default: true
-    pub file_icons: Option<bool>,
-    /// Determines how much space the file finder can take up in relation to the available window width.
-    ///
-    /// Default: small
-    pub modal_max_width: Option<FileFinderWidth>,
-    /// Determines whether the file finder should skip focus for the active file in search results.
-    ///
-    /// Default: true
-    pub skip_focus_for_active_in_search: Option<bool>,
-    /// Determines whether to show the git status in the file finder
-    ///
-    /// Default: true
-    pub git_status: Option<bool>,
-    /// Whether to use gitignored files when searching.
-    /// Only the file Zed had indexed will be used, not necessary all the gitignored files.
-    ///
-    /// Can accept 3 values:
-    /// * `Some(true)`: Use all gitignored files
-    /// * `Some(false)`: Use only the files Zed had indexed
-    /// * `None`: Be smart and search for ignored when called from a gitignored worktree
-    ///
-    /// Default: None
-    pub include_ignored: Option<Option<bool>>,
-}
-
 impl Settings for FileFinderSettings {
     type FileContent = FileFinderSettingsContent;
 

crates/settings/src/settings_content.rs 🔗

@@ -62,6 +62,9 @@ pub struct SettingsContent {
     // todo!() comments?!
     pub base_keymap: Option<BaseKeymapContent>,
 
+    /// Configuration for the collab panel visual settings.
+    pub collaboration_panel: Option<PanelSettingsContent>,
+
     pub debugger: Option<DebuggerSettingsContent>,
 
     /// Configuration for Diagnostics-related features.
@@ -77,15 +80,22 @@ pub struct SettingsContent {
     ///
     /// Default: false
     pub helix_mode: Option<bool>,
+
     /// A map of log scopes to the desired log level.
     /// Useful for filtering out noisy logs or enabling more verbose logging.
     ///
     /// Example: {"log": {"client": "warn"}}
     pub log: Option<HashMap<String, String>>,
 
+    /// Configuration for the Message Editor
+    pub message_editor: Option<MessageEditorSettings>,
+
     /// Configuration for Node-related features
     pub node: Option<NodeBinarySettings>,
 
+    /// Configuration for the Notification Panel
+    pub notification_panel: Option<NotificationPanelSettingsContent>,
+
     pub proxy: Option<String>,
 
     /// The URL of the Zed server to connect to.
@@ -420,3 +430,74 @@ pub enum StatusStyle {
 pub struct ScrollbarSettings {
     pub show: Option<ShowScrollbar>,
 }
+
+#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
+pub struct NotificationPanelSettingsContent {
+    /// Whether to show the panel button in the status bar.
+    ///
+    /// Default: true
+    pub button: Option<bool>,
+    /// Where to dock the panel.
+    ///
+    /// Default: right
+    pub dock: Option<DockPosition>,
+    /// Default width of the panel in pixels.
+    ///
+    /// Default: 300
+    pub default_width: Option<f32>,
+}
+
+#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
+pub struct PanelSettingsContent {
+    /// Whether to show the panel button in the status bar.
+    ///
+    /// Default: true
+    pub button: Option<bool>,
+    /// Where to dock the panel.
+    ///
+    /// Default: left
+    pub dock: Option<DockPosition>,
+    /// Default width of the panel in pixels.
+    ///
+    /// Default: 240
+    pub default_width: Option<f32>,
+}
+
+#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
+pub struct MessageEditorSettings {
+    /// Whether to automatically replace emoji shortcodes with emoji characters.
+    /// For example: typing `:wave:` gets replaced with `👋`.
+    ///
+    /// Default: false
+    pub auto_replace_emoji_shortcode: Option<bool>,
+}
+
+#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)]
+pub struct FileFinderSettingsContent {
+    /// Whether to show file icons in the file finder.
+    ///
+    /// Default: true
+    pub file_icons: Option<bool>,
+    /// Determines how much space the file finder can take up in relation to the available window width.
+    ///
+    /// Default: small
+    pub modal_max_width: Option<FileFinderWidth>,
+    /// Determines whether the file finder should skip focus for the active file in search results.
+    ///
+    /// Default: true
+    pub skip_focus_for_active_in_search: Option<bool>,
+    /// Determines whether to show the git status in the file finder
+    ///
+    /// Default: true
+    pub git_status: Option<bool>,
+    /// Whether to use gitignored files when searching.
+    /// Only the file Zed had indexed will be used, not necessary all the gitignored files.
+    ///
+    /// Can accept 3 values:
+    /// * `Some(true)`: Use all gitignored files
+    /// * `Some(false)`: Use only the files Zed had indexed
+    /// * `None`: Be smart and search for ignored when called from a gitignored worktree
+    ///
+    /// Default: None
+    pub include_ignored: Option<Option<bool>>,
+}

crates/zeta/src/onboarding_modal.rs 🔗

@@ -9,7 +9,7 @@ use gpui::{
     ClickEvent, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, MouseDownEvent, Render,
     linear_color_stop, linear_gradient,
 };
-use language::language_settings::{AllLanguageSettings, EditPredictionProvider};
+use language::language_settings::EditPredictionProvider;
 use settings::update_settings_file;
 use ui::{Vector, VectorName, prelude::*};
 use workspace::{ModalView, Workspace};
@@ -22,8 +22,10 @@ pub struct ZedPredictModal {
 
 pub(crate) fn set_edit_prediction_provider(provider: EditPredictionProvider, cx: &mut App) {
     let fs = <dyn Fs>::global(cx);
-    update_settings_file::<AllLanguageSettings>(fs, cx, move |settings, _| {
+    update_settings_file(fs, cx, move |settings, _| {
         settings
+            .project
+            .all_languages
             .features
             .get_or_insert(Default::default())
             .edit_prediction_provider = Some(provider);