go to line

Conrad Irwin created

Change summary

crates/collab_ui/src/collab_panel.rs                   |  8 -
crates/collab_ui/src/notification_panel.rs             | 10 -
crates/copilot/src/copilot_completion_provider.rs      |  9 -
crates/debugger_ui/src/debugger_panel.rs               | 24 +----
crates/extensions_ui/src/extension_version_selector.rs |  9 +
crates/extensions_ui/src/extensions_ui.rs              | 16 +--
crates/file_finder/src/file_finder.rs                  | 12 +-
crates/file_finder/src/file_finder_settings.rs         |  3 
crates/go_to_line/src/cursor_position.rs               | 46 +++--------
crates/settings/src/settings_content.rs                | 12 ++
crates/settings/src/settings_store.rs                  |  2 
11 files changed, 61 insertions(+), 90 deletions(-)

Detailed changes

crates/collab_ui/src/collab_panel.rs 🔗

@@ -2993,11 +2993,9 @@ impl Panel for CollabPanel {
         _window: &mut Window,
         cx: &mut Context<Self>,
     ) {
-        settings::update_settings_file::<CollaborationPanelSettings>(
-            self.fs.clone(),
-            cx,
-            move |settings, _| settings.workspace.dock = Some(position),
-        );
+        settings::update_settings_file(self.fs.clone(), cx, move |settings, _| {
+            settings.collaboration_panel.get_or_insert_default().dock = Some(position.into())
+        });
     }
 
     fn size(&self, _window: &Window, cx: &App) -> Pixels {

crates/collab_ui/src/notification_panel.rs 🔗

@@ -621,13 +621,9 @@ impl Panel for NotificationPanel {
     }
 
     fn set_position(&mut self, position: DockPosition, _: &mut Window, cx: &mut Context<Self>) {
-        settings::update_settings_file::<NotificationPanelSettings>(
-            self.fs.clone(),
-            cx,
-            move |settings, _| {
-                settings.notification_panel.get_or_insert_default().dock = Some(position)
-            },
-        );
+        settings::update_settings_file(self.fs.clone(), cx, move |settings, _| {
+            settings.notification_panel.get_or_insert_default().dock = Some(position.into())
+        });
     }
 
     fn size(&self, _: &Window, cx: &App) -> Pixels {

crates/copilot/src/copilot_completion_provider.rs 🔗

@@ -281,14 +281,11 @@ mod tests {
     use indoc::indoc;
     use language::{
         Point,
-        language_settings::{
-            AllLanguageSettings, AllLanguageSettingsContent, CompletionSettings, LspInsertMode,
-            WordsCompletionMode,
-        },
+        language_settings::{CompletionSettings, LspInsertMode, WordsCompletionMode},
     };
     use project::Project;
     use serde_json::json;
-    use settings::SettingsStore;
+    use settings::{AllLanguageSettingsContent, SettingsStore};
     use std::future::Future;
     use util::{
         path,
@@ -1128,7 +1125,7 @@ mod tests {
             Project::init_settings(cx);
             workspace::init_settings(cx);
             SettingsStore::update_global(cx, |store: &mut SettingsStore, cx| {
-                store.update_user_settings::<AllLanguageSettings>(cx, f);
+                store.update_user_settings(cx, |settings| f(settings.project.all_languages));
             });
         });
     }

crates/debugger_ui/src/debugger_panel.rs 🔗

@@ -12,7 +12,6 @@ use crate::{
 use anyhow::{Context as _, Result, anyhow};
 use collections::IndexMap;
 use dap::adapters::DebugAdapterName;
-use dap::debugger_settings::DebugPanelDockPosition;
 use dap::{DapRegistry, StartDebuggingRequestArguments};
 use dap::{client::SessionId, debugger_settings::DebuggerSettings};
 use editor::Editor;
@@ -29,7 +28,7 @@ use project::debugger::session::{Session, SessionQuirks, SessionState, SessionSt
 use project::{DebugScenarioContext, Fs, ProjectPath, TaskSourceKind, WorktreeId};
 use project::{Project, debugger::session::ThreadStatus};
 use rpc::proto::{self};
-use settings::{DockPosition, Settings};
+use settings::Settings;
 use std::sync::{Arc, LazyLock};
 use task::{DebugScenario, TaskContext};
 use tree_sitter::{Query, StreamingIterator as _};
@@ -1400,11 +1399,7 @@ impl Panel for DebugPanel {
     }
 
     fn position(&self, _window: &Window, cx: &App) -> DockPosition {
-        match DebuggerSettings::get_global(cx).dock {
-            DockPosition::Left => DockPosition::Left,
-            DockPosition::Bottom => DockPosition::Bottom,
-            DockPosition::Right => DockPosition::Right,
-        }
+        DebuggerSettings::get_global(cx).dock.into()
     }
 
     fn position_is_valid(&self, _: DockPosition) -> bool {
@@ -1426,18 +1421,9 @@ impl Panel for DebugPanel {
             });
         }
 
-        settings::update_settings_file::<DebuggerSettings>(
-            self.fs.clone(),
-            cx,
-            move |settings, _| {
-                let dock = match position {
-                    DockPosition::Left => DebugPanelDockPosition::Left,
-                    DockPosition::Bottom => DebugPanelDockPosition::Bottom,
-                    DockPosition::Right => DebugPanelDockPosition::Right,
-                };
-                settings.dock = dock;
-            },
-        );
+        settings::update_settings_file(self.fs.clone(), cx, move |settings, _| {
+            settings.debugger.get_or_insert_default().dock = position.into();
+        });
     }
 
     fn size(&self, _window: &Window, _: &App) -> Pixels {

crates/extensions_ui/src/extension_version_selector.rs 🔗

@@ -2,7 +2,7 @@ use std::str::FromStr;
 use std::sync::Arc;
 
 use client::ExtensionMetadata;
-use extension_host::{ExtensionSettings, ExtensionStore};
+use extension_host::ExtensionStore;
 use fs::Fs;
 use fuzzy::{StringMatch, StringMatchCandidate, match_strings};
 use gpui::{App, DismissEvent, Entity, EventEmitter, Focusable, Task, WeakEntity, prelude::*};
@@ -183,10 +183,13 @@ impl PickerDelegate for ExtensionVersionSelectorDelegate {
             let extension_id = extension_version.id.clone();
             let version = extension_version.manifest.version.clone();
 
-            update_settings_file::<ExtensionSettings>(self.fs.clone(), cx, {
+            update_settings_file(self.fs.clone(), cx, {
                 let extension_id = extension_id.clone();
                 move |settings, _| {
-                    settings.auto_update_extensions.insert(extension_id, false);
+                    settings
+                        .extension
+                        .auto_update_extensions
+                        .insert(extension_id, false);
                 }
             });
 

crates/extensions_ui/src/extensions_ui.rs 🔗

@@ -20,7 +20,7 @@ use gpui::{
 use num_format::{Locale, ToFormattedString};
 use project::DirectoryLister;
 use release_channel::ReleaseChannel;
-use settings::Settings;
+use settings::{Settings, SettingsContent};
 use strum::IntoEnumIterator as _;
 use theme::ThemeSettings;
 use ui::{
@@ -1269,17 +1269,17 @@ impl ExtensionsPage {
         Label::new(message)
     }
 
-    fn update_settings<T: Settings>(
+    fn update_settings(
         &mut self,
         selection: &ToggleState,
 
         cx: &mut Context<Self>,
-        callback: impl 'static + Send + Fn(&mut T::FileContent, bool),
+        callback: impl 'static + Send + Fn(&mut SettingsContent, bool),
     ) {
         if let Some(workspace) = self.workspace.upgrade() {
             let fs = workspace.read(cx).app_state().fs.clone();
             let selection = *selection;
-            settings::update_settings_file::<T>(fs, cx, move |settings, _| {
+            settings::update_settings_file(fs, cx, move |settings, _| {
                 let value = match selection {
                     ToggleState::Unselected => false,
                     ToggleState::Selected => true,
@@ -1340,11 +1340,9 @@ impl ExtensionsPage {
                         },
                         cx.listener(move |this, selection, _, cx| {
                             telemetry::event!("Vim Mode Toggled", source = "Feature Upsell");
-                            this.update_settings::<VimModeSetting>(
-                                selection,
-                                cx,
-                                |setting, value| setting.vim_mode = Some(value),
-                            );
+                            this.update_settings(selection, cx, |setting, value| {
+                                setting.vim_mode = Some(value)
+                            });
                         }),
                     )),
                 Feature::LanguageBash => FeatureUpsell::new("Shell support is built-in to Zed!")

crates/file_finder/src/file_finder.rs 🔗

@@ -347,16 +347,16 @@ impl FileFinder {
         })
     }
 
-    pub fn modal_max_width(width_setting: Option<FileFinderWidth>, window: &mut Window) -> Pixels {
+    pub fn modal_max_width(width_setting: FileFinderWidth, window: &mut Window) -> Pixels {
         let window_width = window.viewport_size().width;
         let small_width = rems(34.).to_pixels(window.rem_size());
 
         match width_setting {
-            None | Some(FileFinderWidth::Small) => small_width,
-            Some(FileFinderWidth::Full) => window_width,
-            Some(FileFinderWidth::XLarge) => (window_width - Pixels(512.)).max(small_width),
-            Some(FileFinderWidth::Large) => (window_width - Pixels(768.)).max(small_width),
-            Some(FileFinderWidth::Medium) => (window_width - Pixels(1024.)).max(small_width),
+            FileFinderWidth::Small => small_width,
+            FileFinderWidth::Full => window_width,
+            FileFinderWidth::XLarge => (window_width - Pixels(512.)).max(small_width),
+            FileFinderWidth::Large => (window_width - Pixels(768.)).max(small_width),
+            FileFinderWidth::Medium => (window_width - Pixels(1024.)).max(small_width),
         }
     }
 }

crates/file_finder/src/file_finder_settings.rs 🔗

@@ -1,4 +1,3 @@
-use anyhow::Result;
 use schemars::JsonSchema;
 use serde::{Deserialize, Serialize};
 use settings::Settings;
@@ -13,7 +12,7 @@ pub struct FileFinderSettings {
 }
 
 impl Settings for FileFinderSettings {
-    fn from_defaults(content: &settings::SettingsContent, cx: &mut ui::App) -> Self {
+    fn from_defaults(content: &settings::SettingsContent, _cx: &mut ui::App) -> Self {
         let file_finder = content.file_finder.as_ref().unwrap();
 
         Self {

crates/go_to_line/src/cursor_position.rs 🔗

@@ -1,7 +1,5 @@
 use editor::{Editor, EditorSettings, MultiBufferSnapshot};
 use gpui::{App, Entity, FocusHandle, Focusable, Subscription, Task, WeakEntity};
-use schemars::JsonSchema;
-use serde::{Deserialize, Serialize};
 use settings::Settings;
 use std::{fmt::Write, num::NonZeroU32, time::Duration};
 use text::{Point, Selection};
@@ -9,7 +7,7 @@ use ui::{
     Button, ButtonCommon, Clickable, Context, FluentBuilder, IntoElement, LabelSize, ParentElement,
     Render, Tooltip, Window, div,
 };
-use util::paths::FILE_ROW_COLUMN_DELIMITER;
+use util::{MergeFrom, paths::FILE_ROW_COLUMN_DELIMITER};
 use workspace::{StatusItemView, Workspace, item::ItemHandle};
 
 #[derive(Copy, Clone, Debug, Default, PartialOrd, PartialEq)]
@@ -293,41 +291,27 @@ impl StatusItemView for CursorPosition {
     }
 }
 
-#[derive(Clone, Copy, Default, PartialEq, Debug, JsonSchema, Deserialize, Serialize)]
-#[serde(rename_all = "snake_case")]
-pub(crate) enum LineIndicatorFormat {
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub enum LineIndicatorFormat {
     Short,
-    #[default]
     Long,
 }
 
-#[derive(
-    Clone, Copy, Default, Debug, JsonSchema, Deserialize, Serialize, SettingsUi, SettingsKey,
-)]
-#[settings_key(None)]
-pub(crate) struct LineIndicatorFormatContent {
-    line_indicator_format: Option<LineIndicatorFormat>,
+impl From<settings::LineIndicatorFormat> for LineIndicatorFormat {
+    fn from(format: settings::LineIndicatorFormat) -> Self {
+        match format {
+            settings::LineIndicatorFormat::Short => LineIndicatorFormat::Short,
+            settings::LineIndicatorFormat::Long => LineIndicatorFormat::Long,
+        }
+    }
 }
 
 impl Settings for LineIndicatorFormat {
-    type FileContent = LineIndicatorFormatContent;
-
-    fn load(sources: SettingsSources<Self::FileContent>, _: &mut App) -> anyhow::Result<Self> {
-        let format = [
-            sources.release_channel,
-            sources.profile,
-            sources.user,
-            sources.operating_system,
-            Some(sources.default),
-        ]
-        .into_iter()
-        .flatten()
-        .filter_map(|val| val.line_indicator_format)
-        .next()
-        .ok_or_else(Self::missing_default)?;
-
-        Ok(format)
+    fn from_defaults(content: &settings::SettingsContent, _cx: &mut App) -> Self {
+        content.line_indicator_format.unwrap().into()
     }
 
-    fn import_from_vscode(_vscode: &settings::VsCodeSettings, _current: &mut Self::FileContent) {}
+    fn refine(&mut self, content: &settings::SettingsContent, _cx: &mut App) {
+        self.merge_from(&content.line_indicator_format.map(Into::into));
+    }
 }

crates/settings/src/settings_content.rs 🔗

@@ -92,6 +92,8 @@ pub struct SettingsContent {
     /// Example: {"log": {"client": "warn"}}
     pub log: Option<HashMap<String, String>>,
 
+    pub line_indicator_format: Option<LineIndicatorFormat>,
+
     pub outline_panel: Option<OutlinePanelSettingsContent>,
 
     /// Configuration for the Message Editor
@@ -291,7 +293,7 @@ pub struct TelemetrySettingsContent {
     pub metrics: Option<bool>,
 }
 
-#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Clone)]
+#[derive(Default, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Clone)]
 pub struct DebuggerSettingsContent {
     /// Determines the stepping granularity.
     ///
@@ -675,3 +677,11 @@ pub struct IndentGuidesSettingsContent {
     /// When to show the scrollbar in the outline panel.
     pub show: Option<ShowIndentGuides>,
 }
+
+#[derive(Clone, Copy, Default, PartialEq, Debug, JsonSchema, Deserialize, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub enum LineIndicatorFormat {
+    Short,
+    #[default]
+    Long,
+}

crates/settings/src/settings_store.rs 🔗

@@ -74,7 +74,7 @@ pub trait Settings: 'static + Send + Sync + Sized {
 
     /// Use [the helpers in the vscode_import module](crate::vscode_import) to apply known
     /// equivalent settings from a vscode config to our config
-    fn import_from_vscode(vscode: &VsCodeSettings, current: &mut SettingsContent);
+    fn import_from_vscode(_vscode: &VsCodeSettings, _current: &mut SettingsContent) {}
 
     #[track_caller]
     fn register(cx: &mut App)