From 5c7907ad2fb566c787de003e79cfb7ba40364ac2 Mon Sep 17 00:00:00 2001 From: Ben Kunkle Date: Tue, 7 Oct 2025 21:41:48 -0500 Subject: [PATCH] settings_ui: Pre preview launch cleanup (#39733) Closes #ISSUE Release Notes: - N/A *or* Added/Fixed/Improved ... --------- Co-authored-by: Anthony --- crates/settings/src/settings_content.rs | 4 +- .../settings/src/settings_content/terminal.rs | 6 +- .../src/settings_content/workspace.rs | 6 +- crates/settings_ui/src/page_data.rs | 505 ++++++++++-------- crates/settings_ui/src/settings_ui.rs | 27 +- 5 files changed, 283 insertions(+), 265 deletions(-) diff --git a/crates/settings/src/settings_content.rs b/crates/settings/src/settings_content.rs index bb7a972310bfdf4fa7070bbac53b579fc6bcbb93..3599ac4110360c62071ea40bd2c73935fc5116ec 100644 --- a/crates/settings/src/settings_content.rs +++ b/crates/settings/src/settings_content.rs @@ -787,7 +787,9 @@ pub enum ShowIndentGuides { } #[skip_serializing_none] -#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)] +#[derive( + Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default, +)] pub struct IndentGuidesSettingsContent { /// When to show the scrollbar in the outline panel. pub show: Option, diff --git a/crates/settings/src/settings_content/terminal.rs b/crates/settings/src/settings_content/terminal.rs index 1154c1cd6c9a89cba8e4f7a05278fd6ad8d02cff..2a08be84e743debb5b01539621dd33e986b1925a 100644 --- a/crates/settings/src/settings_content/terminal.rs +++ b/crates/settings/src/settings_content/terminal.rs @@ -164,7 +164,9 @@ pub enum WorkingDirectory { } #[skip_serializing_none] -#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)] +#[derive( + Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default, +)] pub struct ScrollbarSettingsContent { /// When to show the scrollbar in the terminal. /// @@ -203,6 +205,7 @@ impl TerminalLineHeight { Copy, Clone, Debug, + Default, Serialize, Deserialize, JsonSchema, @@ -216,6 +219,7 @@ impl TerminalLineHeight { pub enum ShowScrollbar { /// Show the scrollbar if there's important information or /// follow the system's configured behavior. + #[default] Auto, /// Match the system's configured behavior. System, diff --git a/crates/settings/src/settings_content/workspace.rs b/crates/settings/src/settings_content/workspace.rs index e35720a6618e65f88ef5238b1bd278bb4c8e8367..511c883a4386c6b2ea634dc751c0f38fe5c8079c 100644 --- a/crates/settings/src/settings_content/workspace.rs +++ b/crates/settings/src/settings_content/workspace.rs @@ -418,7 +418,7 @@ pub enum PaneSplitDirectionVertical { } #[skip_serializing_none] -#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)] +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Default)] #[serde(rename_all = "snake_case")] pub struct CenteredLayoutSettings { /// The relative width of the left padding of the central pane from the @@ -564,7 +564,9 @@ pub enum ProjectPanelEntrySpacing { } #[skip_serializing_none] -#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)] +#[derive( + Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default, +)] pub struct ProjectPanelIndentGuidesSettings { pub show: Option, } diff --git a/crates/settings_ui/src/page_data.rs b/crates/settings_ui/src/page_data.rs index 5ab86ac37eb1abe2988d0395573158c09e40902a..6f8cc8eb5e8dd0f177cb1fffd5b8916d4e257e73 100644 --- a/crates/settings_ui/src/page_data.rs +++ b/crates/settings_ui/src/page_data.rs @@ -111,32 +111,38 @@ pub(crate) fn settings_data() -> Vec { metadata: None, files: USER, }), - // SettingsPageItem::SectionHeader("Scoped Settings"), - // todo(settings_ui): Implement another setting item type that just shows an edit in settings.json - // files: USER, - // SettingsPageItem::SettingItem(SettingItem { - // title: "Preview Channel", - // description: "Which settings should be activated only in Preview build of Zed", - // field: Box::new(SettingField { - // pick: |settings_content| &settings_content.workspace.use_system_prompts, - // pick_mut: |settings_content| { - // &mut settings_content.workspace.use_system_prompts - // }, - // }), - // metadata: None, - // }), - // files: USER, - // SettingsPageItem::SettingItem(SettingItem { - // title: "Settings Profiles", - // description: "Any number of settings profiles that are temporarily applied on top of your existing user settings.", - // field: Box::new(SettingField { - // pick: |settings_content| &settings_content.workspace.use_system_prompts, - // pick_mut: |settings_content| { - // &mut settings_content.workspace.use_system_prompts - // }, - // }), - // metadata: None, - // }), + SettingsPageItem::SectionHeader("Scoped Settings"), + SettingsPageItem::SettingItem(SettingItem { + // todo(settings_ui): Implement another setting item type that just shows an edit in settings.json + files: USER, + title: "Preview Channel", + description: "Which settings should be activated only in Preview build of Zed", + field: Box::new( + SettingField { + pick: |settings_content| &settings_content.workspace.use_system_prompts, + pick_mut: |settings_content| { + &mut settings_content.workspace.use_system_prompts + }, + } + .unimplemented(), + ), + metadata: None, + }), + SettingsPageItem::SettingItem(SettingItem { + files: USER, + title: "Settings Profiles", + description: "Any number of settings profiles that are temporarily applied on top of your existing user settings.", + field: Box::new( + SettingField { + pick: |settings_content| &settings_content.workspace.use_system_prompts, + pick_mut: |settings_content| { + &mut settings_content.workspace.use_system_prompts + }, + } + .unimplemented(), + ), + metadata: None, + }), SettingsPageItem::SectionHeader("Privacy"), SettingsPageItem::SettingItem(SettingItem { title: "Telemetry Diagnostics", @@ -182,30 +188,36 @@ pub(crate) fn settings_data() -> Vec { SettingsPage { title: "Appearance & Behavior", items: vec![ - // SettingsPageItem::SectionHeader("Theme"), + SettingsPageItem::SectionHeader("Theme"), // todo(settings_ui): Figure out how we want to add these - // files: USER, - // SettingsPageItem::SettingItem(SettingItem { - // title: "Theme Mode", - // description: "How to select the theme", - // field: Box::new(SettingField { - // pick: |settings_content| &settings_content.theme.theme, - // pick_mut: |settings_content| &mut settings_content.theme.theme, - // }), - // metadata: None, - // }), - // files: USER, - // SettingsPageItem::SettingItem(SettingItem { - // title: "Icon Theme", - // // todo(settings_ui) - // // This description is misleading because the icon theme is used in more places than the file explorer) - // description: "Choose the icon theme for file explorer", - // field: Box::new(SettingField { - // pick: |settings_content| &settings_content.theme.icon_theme, - // pick_mut: |settings_content| &mut settings_content.theme.icon_theme, - // }), - // metadata: None, - // }), + SettingsPageItem::SettingItem(SettingItem { + files: USER, + title: "Theme Mode", + description: "How to select the theme", + field: Box::new( + SettingField { + pick: |settings_content| &settings_content.theme.theme, + pick_mut: |settings_content| &mut settings_content.theme.theme, + } + .unimplemented(), + ), + metadata: None, + }), + SettingsPageItem::SettingItem(SettingItem { + files: USER, + title: "Icon Theme", + // todo(settings_ui) + // This description is misleading because the icon theme is used in more places than the file explorer) + description: "Choose the icon theme for file explorer", + field: Box::new( + SettingField { + pick: |settings_content| &settings_content.theme.icon_theme, + pick_mut: |settings_content| &mut settings_content.theme.icon_theme, + } + .unimplemented(), + ), + metadata: None, + }), SettingsPageItem::SectionHeader("Fonts"), SettingsPageItem::SettingItem(SettingItem { title: "Buffer Font Family", @@ -238,16 +250,21 @@ pub(crate) fn settings_data() -> Vec { files: USER, }), // todo(settings_ui): This needs custom ui - // files: USER, - // SettingsPageItem::SettingItem(SettingItem { - // title: "Buffer Line Height", - // description: "Line height for editor text", - // field: Box::new(SettingField { - // pick: |settings_content| &settings_content.theme.buffer_line_height, - // pick_mut: |settings_content| &mut settings_content.theme.buffer_line_height, - // }), - // metadata: None, - // }), + SettingsPageItem::SettingItem(SettingItem { + files: USER, + title: "Buffer Line Height", + description: "Line height for editor text", + field: Box::new( + SettingField { + pick: |settings_content| &settings_content.theme.buffer_line_height, + pick_mut: |settings_content| { + &mut settings_content.theme.buffer_line_height + }, + } + .unimplemented(), + ), + metadata: None, + }), SettingsPageItem::SettingItem(SettingItem { title: "UI Font Family", description: "Font family for UI elements", @@ -478,58 +495,54 @@ pub(crate) fn settings_data() -> Vec { metadata: None, files: USER, }), - // files: USER, - // SettingsPageItem::SettingItem(SettingItem { - // title: "Centered Layout Left Padding", - // description: "Left padding for centered layout", - // field: Box::new(SettingField { - // pick: |settings_content| { - // if let Some(centered_layout) = - // &settings_content.workspace.centered_layout - // { - // ¢ered_layout.left_padding - // } else { - // &None - // } - // }, - // pick_mut: |settings_content| { - // if let Some(mut centered_layout) = - // settings_content.workspace.centered_layout - // { - // &mut centered_layout.left_padding - // } else { - // &mut None - // } - // }, - // }), - // metadata: None, - // }), - // files: USER, - // SettingsPageItem::SettingItem(SettingItem { - // title: "Centered Layout Right Padding", - // description: "Right padding for centered layout", - // field: Box::new(SettingField { - // pick: |settings_content| { - // if let Some(centered_layout) = - // &settings_content.workspace.centered_layout - // { - // ¢ered_layout.right_padding - // } else { - // &None - // } - // }, - // pick_mut: |settings_content| { - // if let Some(mut centered_layout) = - // settings_content.workspace.centered_layout - // { - // &mut centered_layout.right_padding - // } else { - // &mut None - // } - // }, - // }), - // metadata: None, - // }), + SettingsPageItem::SettingItem(SettingItem { + files: USER, + title: "Centered Layout Left Padding", + description: "Left padding for centered layout", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(centered_layout) = + &settings_content.workspace.centered_layout + { + ¢ered_layout.left_padding + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .workspace + .centered_layout + .get_or_insert_default() + .left_padding + }, + }), + metadata: None, + }), + SettingsPageItem::SettingItem(SettingItem { + files: USER, + title: "Centered Layout Right Padding", + description: "Right padding for centered layout", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(centered_layout) = + &settings_content.workspace.centered_layout + { + ¢ered_layout.right_padding + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .workspace + .centered_layout + .get_or_insert_default() + .right_padding + }, + }), + metadata: None, + }), SettingsPageItem::SettingItem(SettingItem { title: "Zoomed Padding", description: "Whether to show padding for zoomed panels", @@ -1442,18 +1455,23 @@ pub(crate) fn settings_data() -> Vec { metadata: None, files: USER, }), - // files: USER, - // SettingsPageItem::SettingItem(SettingItem { - // title: "Maximum Tabs", - // description: "Maximum open tabs in a pane. Will not close an unsaved tab", - // // todo(settings_ui): The default for this value is null and it's use in code - // // is complex, so I'm going to come back to this later - // field: Box::new(SettingField { - // pick: |settings_content| &settings_content.workspace.max_tabs, - // pick_mut: |settings_content| &mut settings_content.workspace.max_tabs, - // }), - // metadata: None, - // }), + SettingsPageItem::SettingItem(SettingItem { + files: USER, + title: "Maximum Tabs", + description: "Maximum open tabs in a pane. Will not close an unsaved tab", + // todo(settings_ui): The default for this value is null and it's use in code + // is complex, so I'm going to come back to this later + field: Box::new( + SettingField { + pick: |settings_content| &settings_content.workspace.max_tabs, + pick_mut: |settings_content| { + &mut settings_content.workspace.max_tabs + }, + } + .unimplemented(), + ), + metadata: None, + }), SettingsPageItem::SectionHeader("Toolbar"), SettingsPageItem::SettingItem(SettingItem { title: "Breadcrumbs", @@ -2207,27 +2225,30 @@ pub(crate) fn settings_data() -> Vec { files: USER, }), // todo: null by default - // files: USER, - // SettingsPageItem::SettingItem(SettingItem { - // title: "Include Ignored", - // description: "Whether to use gitignored files when searching", - // field: Box::new(SettingField { - // pick: |settings_content| { - // if let Some(file_finder) = &settings_content.file_finder { - // &file_finder.include_ignored - // } else { - // &None - // } - // }, - // pick_mut: |settings_content| { - // &mut settings_content - // .file_finder - // .get_or_insert_default() - // .include_ignored - // }, - // }), - // metadata: None, - // }), + SettingsPageItem::SettingItem(SettingItem { + title: "Include Ignored", + description: "Whether to use gitignored files when searching", + field: Box::new( + SettingField { + pick: |settings_content| { + if let Some(file_finder) = &settings_content.file_finder { + &file_finder.include_ignored + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .file_finder + .get_or_insert_default() + .include_ignored + }, + } + .unimplemented(), + ), + metadata: None, + files: USER, + }), ], }, SettingsPage { @@ -2483,31 +2504,34 @@ pub(crate) fn settings_data() -> Vec { metadata: None, files: USER, }), - // files: USER, - // SettingsPageItem::SettingItem(SettingItem { - // title: "Scrollbar Show", - // description: "When to show the scrollbar in the project panel", - // field: Box::new(SettingField { - // pick: |settings_content| { - // if let Some(project_panel) = &settings_content.project_panel { - // if let Some(scrollbar) = &project_panel.scrollbar { - // &scrollbar.show - // } else { - // &None - // } - // } else { - // &None - // } - // }, - // pick_mut: |settings_content| { - // &mut settings_content - // .project_panel - // .get_or_insert_default() - // .scrollbar - // }, - // }), - // metadata: None, - // }), + SettingsPageItem::SettingItem(SettingItem { + title: "Scrollbar Show", + description: "When to show the scrollbar in the project panel", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(project_panel) = &settings_content.project_panel + && let Some(scrollbar) = &project_panel.scrollbar + && scrollbar.show.is_some() + { + &scrollbar.show + } else if let Some(scrollbar) = &settings_content.editor.scrollbar { + &scrollbar.show + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .project_panel + .get_or_insert_default() + .scrollbar + .get_or_insert_default() + .show + }, + }), + metadata: None, + files: USER, + }), SettingsPageItem::SettingItem(SettingItem { title: "Show Diagnostics", description: "Which files containing diagnostic errors/warnings to mark in the project panel", @@ -2550,33 +2574,36 @@ pub(crate) fn settings_data() -> Vec { metadata: None, files: USER, }), - // files: USER, - // SettingsPageItem::SettingItem(SettingItem { - // title: "Indent Guides Show", - // description: "When to show indent guides in the project panel", - // field: Box::new(SettingField { - // pick: |settings_content| { - // if let Some(project_panel) = &settings_content.project_panel { - // if let Some(indent_guides) = &project_panel.indent_guides { - // &indent_guides.show - // } else { - // &None - // } - // } else { - // &None - // } - // }, - // pick_mut: |settings_content| { - // &mut settings_content - // .project_panel - // .get_or_insert_default() - // .indent_guides - // .get_or_insert_default() - // .show - // }, - // }), - // metadata: None, - // }), + SettingsPageItem::SettingItem(SettingItem { + files: USER, + title: "Indent Guides Show", + description: "When to show indent guides in the project panel", + field: Box::new( + SettingField { + pick: |settings_content| { + if let Some(project_panel) = &settings_content.project_panel { + if let Some(indent_guides) = &project_panel.indent_guides { + &indent_guides.show + } else { + &None + } + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .project_panel + .get_or_insert_default() + .indent_guides + .get_or_insert_default() + .show + }, + } + .unimplemented(), + ), + metadata: None, + }), SettingsPageItem::SettingItem(SettingItem { title: "Drag and Drop", description: "Whether to enable drag-and-drop operations in the project panel", @@ -2825,33 +2852,36 @@ pub(crate) fn settings_data() -> Vec { metadata: None, files: USER, }), - // files: USER, - // SettingsPageItem::SettingItem(SettingItem { - // title: "Indent Guides Show", - // description: "When to show indent guides in the outline panel", - // field: Box::new(SettingField { - // pick: |settings_content| { - // if let Some(outline_panel) = &settings_content.outline_panel { - // if let Some(indent_guides) = &outline_panel.indent_guides { - // &indent_guides.show - // } else { - // &None - // } - // } else { - // &None - // } - // }, - // pick_mut: |settings_content| { - // &mut settings_content - // .outline_panel - // .get_or_insert_default() - // .indent_guides - // .get_or_insert_default() - // .show - // }, - // }), - // metadata: None, - // }), + SettingsPageItem::SettingItem(SettingItem { + files: USER, + title: "Indent Guides Show", + description: "When to show indent guides in the outline panel", + field: Box::new( + SettingField { + pick: |settings_content| { + if let Some(outline_panel) = &settings_content.outline_panel { + if let Some(indent_guides) = &outline_panel.indent_guides { + &indent_guides.show + } else { + &None + } + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .outline_panel + .get_or_insert_default() + .indent_guides + .get_or_insert_default() + .show + }, + } + .unimplemented(), + ), + metadata: None, + }), SettingsPageItem::SectionHeader("Git Panel"), SettingsPageItem::SettingItem(SettingItem { title: "Button", @@ -3298,18 +3328,21 @@ pub(crate) fn settings_data() -> Vec { items: vec![ SettingsPageItem::SectionHeader("Network"), // todo(settings_ui): Proxy needs a default - // files: USER, - // SettingsPageItem::SettingItem(SettingItem { - // title: "Proxy", - // description: "The proxy to use for network requests", - // field: Box::new(SettingField { - // pick: |settings_content| &settings_content.proxy, - // pick_mut: |settings_content| &mut settings_content.proxy, - // }), - // metadata: Some(Box::new(SettingsFieldMetadata { - // placeholder: Some("socks5h://localhost:10808"), - // })), - // }), + SettingsPageItem::SettingItem(SettingItem { + title: "Proxy", + description: "The proxy to use for network requests", + field: Box::new( + SettingField { + pick: |settings_content| &settings_content.proxy, + pick_mut: |settings_content| &mut settings_content.proxy, + } + .unimplemented(), + ), + metadata: Some(Box::new(SettingsFieldMetadata { + placeholder: Some("socks5h://localhost:10808"), + })), + files: USER, + }), SettingsPageItem::SettingItem(SettingItem { title: "Server URL", description: "The URL of the Zed server to connect to", @@ -4953,7 +4986,7 @@ fn language_settings_data() -> Vec { }), SettingsPageItem::SettingItem(SettingItem { title: "Toggle On Modifiers Press", - description: "Toggles inlay hints (hides or shows) when the user | LOCAL presses the modifiers specified", + description: "Toggles inlay hints (hides or shows) when the user presses the modifiers specified", field: Box::new( SettingField { pick: |settings_content| { diff --git a/crates/settings_ui/src/settings_ui.rs b/crates/settings_ui/src/settings_ui.rs index e9b50b716171d0e479df01b697c8189373de154f..b5d76d4c3e0cc0750fd7001f6d5343d9f8b98964 100644 --- a/crates/settings_ui/src/settings_ui.rs +++ b/crates/settings_ui/src/settings_ui.rs @@ -490,7 +490,8 @@ pub struct SettingsWindow { pages: Vec, search_bar: Entity, search_task: Option>, - navbar_entry: usize, // Index into pages - should probably be (usize, Option) for section + page + /// Index into navbar_entries + navbar_entry: usize, navbar_entries: Vec, list_handle: UniformListScrollHandle, search_matches: Vec>, @@ -1134,29 +1135,6 @@ impl SettingsWindow { cx.notify(); } - fn calculate_navbar_entry_from_scroll_position(&mut self) { - let top = self.scroll_handle.top_item(); - let bottom = self.scroll_handle.bottom_item(); - - let scroll_index = (top + bottom) / 2; - let scroll_index = scroll_index.clamp(top, bottom); - let mut page_index = self.navbar_entry; - - while !self.navbar_entries[page_index].is_root { - page_index -= 1; - } - - if self.navbar_entries[page_index].expanded { - let section_index = self - .page_items() - .take(scroll_index + 1) - .filter(|item| matches!(item, SettingsPageItem::SectionHeader(_))) - .count(); - - self.navbar_entry = section_index + page_index; - } - } - fn fetch_files(&mut self, cx: &mut Context) { let prev_files = self.files.clone(); let settings_store = cx.global::(); @@ -1602,7 +1580,6 @@ impl SettingsWindow { impl Render for SettingsWindow { fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { let ui_font = theme::setup_ui_font(window, cx); - self.calculate_navbar_entry_from_scroll_position(); div() .id("settings-window")