diff --git a/crates/settings_ui/src/page_data.rs b/crates/settings_ui/src/page_data.rs index d51060eae17e6669f5b58e519d499d4e470f2334..5ab86ac37eb1abe2988d0395573158c09e40902a 100644 --- a/crates/settings_ui/src/page_data.rs +++ b/crates/settings_ui/src/page_data.rs @@ -3,11 +3,11 @@ use std::sync::Arc; use ui::{IntoElement, SharedString}; use crate::{ - SettingField, SettingItem, SettingsFieldMetadata, SettingsPage, SettingsPageItem, SubPageLink, - sub_page_stack, + LOCAL, SettingField, SettingItem, SettingsFieldMetadata, SettingsPage, SettingsPageItem, + SubPageLink, USER, sub_page_stack, }; -pub(crate) fn user_settings_data() -> Vec { +pub(crate) fn settings_data() -> Vec { vec![ SettingsPage { title: "General", @@ -21,6 +21,7 @@ pub(crate) fn user_settings_data() -> Vec { pick_mut: |settings_content| &mut settings_content.workspace.confirm_quit, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Restore On Startup", @@ -32,6 +33,7 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Restore File State", @@ -43,6 +45,7 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Close on File Delete", @@ -54,6 +57,7 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "When Closing With No Tabs", @@ -67,6 +71,7 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "On Last Window Closed", @@ -78,6 +83,7 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Use System Path Prompts", @@ -91,6 +97,7 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Use System Prompts", @@ -102,9 +109,11 @@ pub(crate) fn user_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", @@ -116,6 +125,7 @@ pub(crate) fn user_settings_data() -> Vec { // }), // 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.", @@ -147,6 +157,7 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Telemetry Metrics", @@ -164,6 +175,7 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER, }), ], }, @@ -172,6 +184,7 @@ pub(crate) fn user_settings_data() -> Vec { items: vec![ // 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", @@ -181,6 +194,7 @@ pub(crate) fn user_settings_data() -> Vec { // }), // metadata: None, // }), + // files: USER, // SettingsPageItem::SettingItem(SettingItem { // title: "Icon Theme", // // todo(settings_ui) @@ -201,6 +215,7 @@ pub(crate) fn user_settings_data() -> Vec { pick_mut: |settings_content| &mut settings_content.theme.buffer_font_family, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Buffer Font Size", @@ -210,6 +225,7 @@ pub(crate) fn user_settings_data() -> Vec { pick_mut: |settings_content| &mut settings_content.theme.buffer_font_size, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Buffer Font Weight", @@ -219,8 +235,10 @@ pub(crate) fn user_settings_data() -> Vec { pick_mut: |settings_content| &mut settings_content.theme.buffer_font_weight, }), metadata: None, + files: USER, }), // todo(settings_ui): This needs custom ui + // files: USER, // SettingsPageItem::SettingItem(SettingItem { // title: "Buffer Line Height", // description: "Line height for editor text", @@ -238,6 +256,7 @@ pub(crate) fn user_settings_data() -> Vec { pick_mut: |settings_content| &mut settings_content.theme.ui_font_family, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "UI Font Size", @@ -247,6 +266,7 @@ pub(crate) fn user_settings_data() -> Vec { pick_mut: |settings_content| &mut settings_content.theme.ui_font_size, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "UI Font Weight", @@ -256,6 +276,7 @@ pub(crate) fn user_settings_data() -> Vec { pick_mut: |settings_content| &mut settings_content.theme.ui_font_weight, }), metadata: None, + files: USER, }), SettingsPageItem::SectionHeader("Keymap"), SettingsPageItem::SettingItem(SettingItem { @@ -266,6 +287,7 @@ pub(crate) fn user_settings_data() -> Vec { pick_mut: |settings_content| &mut settings_content.base_keymap, }), metadata: None, + files: USER, }), // todo(settings_ui): Vim/Helix Mode should be apart of one type because it's undefined // behavior to have them both enabled at the same time @@ -277,6 +299,7 @@ pub(crate) fn user_settings_data() -> Vec { pick_mut: |settings_content| &mut settings_content.vim_mode, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Helix Mode", @@ -286,6 +309,7 @@ pub(crate) fn user_settings_data() -> Vec { pick_mut: |settings_content| &mut settings_content.helix_mode, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Multi Cursor Modifier", @@ -297,6 +321,7 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER, }), SettingsPageItem::SectionHeader("Cursor"), SettingsPageItem::SettingItem(SettingItem { @@ -307,6 +332,7 @@ pub(crate) fn user_settings_data() -> Vec { pick_mut: |settings_content| &mut settings_content.editor.cursor_blink, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Cursor Shape", @@ -316,6 +342,7 @@ pub(crate) fn user_settings_data() -> Vec { pick_mut: |settings_content| &mut settings_content.editor.cursor_shape, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Hide Mouse", @@ -325,6 +352,7 @@ pub(crate) fn user_settings_data() -> Vec { pick_mut: |settings_content| &mut settings_content.editor.hide_mouse, }), metadata: None, + files: USER, }), SettingsPageItem::SectionHeader("Highlighting"), SettingsPageItem::SettingItem(SettingItem { @@ -337,6 +365,7 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Current Line Highlight", @@ -348,6 +377,7 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Selection Highlight", @@ -359,6 +389,7 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Rounded Selection", @@ -368,6 +399,7 @@ pub(crate) fn user_settings_data() -> Vec { pick_mut: |settings_content| &mut settings_content.editor.rounded_selection, }), metadata: None, + files: USER, }), SettingsPageItem::SectionHeader("Guides"), SettingsPageItem::SettingItem(SettingItem { @@ -390,29 +422,26 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), // todo(settings_ui): This needs a custom component - // SettingsPageItem::SettingItem(SettingItem { - // title: "Wrap Guides", - // description: "Character counts at which to show wrap guides", - // field: Box::new(SettingField { - // pick: |settings_content| { - // &settings_content - // .project - // .all_languages - // .defaults - // .wrap_guides - // }, - // pick_mut: |settings_content| { - // &mut settings_content - // .project - // .all_languages - // .defaults - // .wrap_guides - // }, - // }), - // metadata: None, - // }), + SettingsPageItem::SettingItem(SettingItem { + title: "Wrap Guides", + description: "Character counts at which to show wrap guides", + field: Box::new( + SettingField { + pick: |settings_content| { + &settings_content.project.all_languages.defaults.wrap_guides + }, + pick_mut: |settings_content| { + &mut settings_content.project.all_languages.defaults.wrap_guides + }, + } + .unimplemented(), + ), + metadata: None, + files: USER | LOCAL, + }), SettingsPageItem::SectionHeader("Whitespace"), SettingsPageItem::SettingItem(SettingItem { title: "Show Whitespace", @@ -434,6 +463,7 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SectionHeader("Layout"), SettingsPageItem::SettingItem(SettingItem { @@ -446,7 +476,9 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER, }), + // files: USER, // SettingsPageItem::SettingItem(SettingItem { // title: "Centered Layout Left Padding", // description: "Left padding for centered layout", @@ -472,6 +504,7 @@ pub(crate) fn user_settings_data() -> Vec { // }), // metadata: None, // }), + // files: USER, // SettingsPageItem::SettingItem(SettingItem { // title: "Centered Layout Right Padding", // description: "Right padding for centered layout", @@ -505,6 +538,7 @@ pub(crate) fn user_settings_data() -> Vec { pick_mut: |settings_content| &mut settings_content.workspace.zoomed_padding, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { title: "Use System Window Tabs", @@ -516,6 +550,7 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER, }), SettingsPageItem::SectionHeader("Window"), // todo(settings_ui): Should we filter by platform? @@ -529,3770 +564,3280 @@ pub(crate) fn user_settings_data() -> Vec { }, }), metadata: None, + files: USER, }), ], }, SettingsPage { title: "Editor", + items: { + let mut items = vec![ + SettingsPageItem::SectionHeader("Search"), + SettingsPageItem::SettingItem(SettingItem { + title: "Search Wrap", + description: "Whether the editor search results will loop", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.editor.search_wrap, + pick_mut: |settings_content| &mut settings_content.editor.search_wrap, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Seed Search Query From Cursor", + description: "When to populate a new search's query based on the text under the cursor", + field: Box::new(SettingField { + pick: |settings_content| { + &settings_content.editor.seed_search_query_from_cursor + }, + pick_mut: |settings_content| { + &mut settings_content.editor.seed_search_query_from_cursor + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Use Smartcase Search", + description: "Whether to use smartcase (i.e., case-sensitive) search", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.editor.use_smartcase_search, + pick_mut: |settings_content| { + &mut settings_content.editor.use_smartcase_search + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SectionHeader("Editor Behavior"), + SettingsPageItem::SettingItem(SettingItem { + title: "Redact Private Values", + description: "Hide the values of variables in private files", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.editor.redact_private_values, + pick_mut: |settings_content| { + &mut settings_content.editor.redact_private_values + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Middle Click Paste", + description: "Whether to enable middle-click paste on Linux", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.editor.middle_click_paste, + pick_mut: |settings_content| { + &mut settings_content.editor.middle_click_paste + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Double Click In Multibuffer", + description: "What to do when multibuffer is double-clicked in some of its excerpts", + field: Box::new(SettingField { + pick: |settings_content| { + &settings_content.editor.double_click_in_multibuffer + }, + pick_mut: |settings_content| { + &mut settings_content.editor.double_click_in_multibuffer + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Go To Definition Fallback", + description: "Whether to follow-up empty go to definition responses from the language server", + field: Box::new(SettingField { + pick: |settings_content| { + &settings_content.editor.go_to_definition_fallback + }, + pick_mut: |settings_content| { + &mut settings_content.editor.go_to_definition_fallback + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Expand Excerpt Lines", + description: "How many lines to expand the multibuffer excerpts by default", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.editor.expand_excerpt_lines, + pick_mut: |settings_content| { + &mut settings_content.editor.expand_excerpt_lines + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Excerpt Context Lines", + description: "How many lines of context to provide in multibuffer excerpts by default", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.editor.excerpt_context_lines, + pick_mut: |settings_content| { + &mut settings_content.editor.excerpt_context_lines + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Minimum Contrast For Highlights", + description: "The minimum APCA perceptual contrast to maintain when rendering text over highlight backgrounds", + field: Box::new(SettingField { + pick: |settings_content| { + &settings_content.editor.minimum_contrast_for_highlights + }, + pick_mut: |settings_content| { + &mut settings_content.editor.minimum_contrast_for_highlights + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SectionHeader("Scrolling"), + SettingsPageItem::SettingItem(SettingItem { + title: "Scroll Beyond Last Line", + description: "Whether the editor will scroll beyond the last line", + field: Box::new(SettingField { + pick: |settings_content| { + &settings_content.editor.scroll_beyond_last_line + }, + pick_mut: |settings_content| { + &mut settings_content.editor.scroll_beyond_last_line + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Vertical Scroll Margin", + description: "The number of lines to keep above/below the cursor when auto-scrolling", + field: Box::new(SettingField { + pick: |settings_content| { + &settings_content.editor.vertical_scroll_margin + }, + pick_mut: |settings_content| { + &mut settings_content.editor.vertical_scroll_margin + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Horizontal Scroll Margin", + description: "The number of characters to keep on either side when scrolling with the mouse", + field: Box::new(SettingField { + pick: |settings_content| { + &settings_content.editor.horizontal_scroll_margin + }, + pick_mut: |settings_content| { + &mut settings_content.editor.horizontal_scroll_margin + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Scroll Sensitivity", + description: "Scroll sensitivity multiplier for both horizontal and vertical scrolling", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.editor.scroll_sensitivity, + pick_mut: |settings_content| { + &mut settings_content.editor.scroll_sensitivity + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Fast Scroll Sensitivity", + description: "Fast Scroll sensitivity multiplier for both horizontal and vertical scrolling", + field: Box::new(SettingField { + pick: |settings_content| { + &settings_content.editor.fast_scroll_sensitivity + }, + pick_mut: |settings_content| { + &mut settings_content.editor.fast_scroll_sensitivity + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Autoscroll On Clicks", + description: "Whether to scroll when clicking near the edge of the visible text area", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.editor.autoscroll_on_clicks, + pick_mut: |settings_content| { + &mut settings_content.editor.autoscroll_on_clicks + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SectionHeader("Signature Help"), + SettingsPageItem::SettingItem(SettingItem { + title: "Auto Signature Help", + description: "Whether to automatically show a signature help pop-up or not", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.editor.auto_signature_help, + pick_mut: |settings_content| { + &mut settings_content.editor.auto_signature_help + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Show Signature Help After Edits", + description: "Whether to show the signature help pop-up after completions or bracket pairs inserted", + field: Box::new(SettingField { + pick: |settings_content| { + &settings_content.editor.show_signature_help_after_edits + }, + pick_mut: |settings_content| { + &mut settings_content.editor.show_signature_help_after_edits + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Snippet Sort Order", + description: "Determines how snippets are sorted relative to other completion items", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.editor.snippet_sort_order, + pick_mut: |settings_content| { + &mut settings_content.editor.snippet_sort_order + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SectionHeader("Hover"), + SettingsPageItem::SettingItem(SettingItem { + title: "Hover Popover Enabled", + description: "Whether to show the informational hover box when moving the mouse over symbols in the editor", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.editor.hover_popover_enabled, + pick_mut: |settings_content| { + &mut settings_content.editor.hover_popover_enabled + }, + }), + metadata: None, + files: USER, + }), + // todo(settings ui): add units to this number input + SettingsPageItem::SettingItem(SettingItem { + title: "Hover Popover Delay", + description: "Time to wait in milliseconds before showing the informational hover box", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.editor.hover_popover_delay, + pick_mut: |settings_content| { + &mut settings_content.editor.hover_popover_delay + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SectionHeader("Code Actions"), + SettingsPageItem::SettingItem(SettingItem { + title: "Inline Code Actions", + description: "Whether to show code action button at start of buffer line", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.editor.inline_code_actions, + pick_mut: |settings_content| { + &mut settings_content.editor.inline_code_actions + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SectionHeader("Selection"), + SettingsPageItem::SettingItem(SettingItem { + title: "Drag And Drop Selection", + description: "Whether to enable drag and drop selection", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(drag_and_drop) = + &settings_content.editor.drag_and_drop_selection + { + &drag_and_drop.enabled + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .drag_and_drop_selection + .get_or_insert_default() + .enabled + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Drag And Drop Selection Delay", + description: "Delay in milliseconds before drag and drop selection starts", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(drag_and_drop) = + &settings_content.editor.drag_and_drop_selection + { + &drag_and_drop.delay + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .drag_and_drop_selection + .get_or_insert_default() + .delay + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SectionHeader("Gutter"), + SettingsPageItem::SettingItem(SettingItem { + title: "Show Line Numbers", + description: "Whether to show line numbers in the gutter", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(gutter) = &settings_content.editor.gutter { + &gutter.line_numbers + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .gutter + .get_or_insert_default() + .line_numbers + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Relative Line Numbers", + description: "Whether the line numbers on editors gutter are relative or not", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.editor.relative_line_numbers, + pick_mut: |settings_content| { + &mut settings_content.editor.relative_line_numbers + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Show Runnables", + description: "Whether to show runnable buttons in the gutter", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(gutter) = &settings_content.editor.gutter { + &gutter.runnables + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .gutter + .get_or_insert_default() + .runnables + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Show Breakpoints", + description: "Whether to show breakpoints in the gutter", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(gutter) = &settings_content.editor.gutter { + &gutter.breakpoints + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .gutter + .get_or_insert_default() + .breakpoints + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Show Folds", + description: "Whether to show code folding controls in the gutter", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(gutter) = &settings_content.editor.gutter { + &gutter.folds + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content.editor.gutter.get_or_insert_default().folds + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Min Line Number Digits", + description: "Minimum number of characters to reserve space for in the gutter.", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(gutter) = &settings_content.editor.gutter { + &gutter.min_line_number_digits + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .gutter + .get_or_insert_default() + .min_line_number_digits + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SectionHeader("Scrollbar"), + SettingsPageItem::SettingItem(SettingItem { + title: "Show", + description: "When to show the scrollbar in the editor", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(scrollbar) = &settings_content.editor.scrollbar { + &scrollbar.show + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .scrollbar + .get_or_insert_default() + .show + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Cursors", + description: "Whether to show cursor positions in the scrollbar", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(scrollbar) = &settings_content.editor.scrollbar { + &scrollbar.cursors + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .scrollbar + .get_or_insert_default() + .cursors + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Git Diff", + description: "Whether to show git diff indicators in the scrollbar", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(scrollbar) = &settings_content.editor.scrollbar { + &scrollbar.git_diff + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .scrollbar + .get_or_insert_default() + .git_diff + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Search Results", + description: "Whether to show buffer search result indicators in the scrollbar", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(scrollbar) = &settings_content.editor.scrollbar { + &scrollbar.search_results + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .scrollbar + .get_or_insert_default() + .search_results + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Selected Text", + description: "Whether to show selected text occurrences in the scrollbar", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(scrollbar) = &settings_content.editor.scrollbar { + &scrollbar.selected_text + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .scrollbar + .get_or_insert_default() + .selected_text + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Selected Symbol", + description: "Whether to show selected symbol occurrences in the scrollbar", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(scrollbar) = &settings_content.editor.scrollbar { + &scrollbar.selected_symbol + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .scrollbar + .get_or_insert_default() + .selected_symbol + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Diagnostics", + description: "Which diagnostic indicators to show in the scrollbar", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(scrollbar) = &settings_content.editor.scrollbar { + &scrollbar.diagnostics + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .scrollbar + .get_or_insert_default() + .diagnostics + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Horizontal Scrollbar", + description: "When false, forcefully disables the horizontal scrollbar", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(scrollbar) = &settings_content.editor.scrollbar { + if let Some(axes) = &scrollbar.axes { + &axes.horizontal + } else { + &None + } + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .scrollbar + .get_or_insert_default() + .axes + .get_or_insert_default() + .horizontal + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Vertical Scrollbar", + description: "When false, forcefully disables the vertical scrollbar", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(scrollbar) = &settings_content.editor.scrollbar { + if let Some(axes) = &scrollbar.axes { + &axes.vertical + } else { + &None + } + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .scrollbar + .get_or_insert_default() + .axes + .get_or_insert_default() + .vertical + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SectionHeader("Minimap"), + SettingsPageItem::SettingItem(SettingItem { + title: "Show", + description: "When to show the minimap in the editor", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(minimap) = &settings_content.editor.minimap { + &minimap.show + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content.editor.minimap.get_or_insert_default().show + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Display In", + description: "Where to show the minimap in the editor", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(minimap) = &settings_content.editor.minimap { + &minimap.display_in + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .minimap + .get_or_insert_default() + .display_in + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Thumb", + description: "When to show the minimap thumb", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(minimap) = &settings_content.editor.minimap { + &minimap.thumb + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .minimap + .get_or_insert_default() + .thumb + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Thumb Border", + description: "Border style for the minimap's scrollbar thumb", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(minimap) = &settings_content.editor.minimap { + &minimap.thumb_border + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .minimap + .get_or_insert_default() + .thumb_border + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Current Line Highlight", + description: "How to highlight the current line in the minimap", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(minimap) = &settings_content.editor.minimap + && minimap.current_line_highlight.is_some() + { + &minimap.current_line_highlight + } else { + &settings_content.editor.current_line_highlight + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .minimap + .get_or_insert_default() + .current_line_highlight + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Max Width Columns", + description: "Maximum number of columns to display in the minimap", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(minimap) = &settings_content.editor.minimap { + &minimap.max_width_columns + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .minimap + .get_or_insert_default() + .max_width_columns + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SectionHeader("Tabs"), + SettingsPageItem::SettingItem(SettingItem { + title: "Show Tab Bar", + description: "Whether or not to show the tab bar in the editor", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(tab_bar) = &settings_content.tab_bar { + &tab_bar.show + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content.tab_bar.get_or_insert_default().show + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Show Git Status In Tabs", + description: "Whether to show the Git file status on a tab item", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(tabs) = &settings_content.tabs { + &tabs.git_status + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content.tabs.get_or_insert_default().git_status + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Show File Icons In Tabs", + description: "Whether to show the file icon for a tab", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(tabs) = &settings_content.tabs { + &tabs.file_icons + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content.tabs.get_or_insert_default().file_icons + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Tab Close Position", + description: "Position of the close button in a tab", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(tabs) = &settings_content.tabs { + &tabs.close_position + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content.tabs.get_or_insert_default().close_position + }, + }), + 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::SectionHeader("Toolbar"), + SettingsPageItem::SettingItem(SettingItem { + title: "Breadcrumbs", + description: "Whether to show breadcrumbs", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(toolbar) = &settings_content.editor.toolbar { + &toolbar.breadcrumbs + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .toolbar + .get_or_insert_default() + .breadcrumbs + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Quick Actions", + description: "Whether to show quick action buttons (e.g., search, selection, editor controls, etc.)", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(toolbar) = &settings_content.editor.toolbar { + &toolbar.quick_actions + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .toolbar + .get_or_insert_default() + .quick_actions + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Selections Menu", + description: "Whether to show the selections menu in the editor toolbar", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(toolbar) = &settings_content.editor.toolbar { + &toolbar.selections_menu + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .toolbar + .get_or_insert_default() + .selections_menu + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Agent Review", + description: "Whether to show agent review buttons in the editor toolbar", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(toolbar) = &settings_content.editor.toolbar { + &toolbar.agent_review + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .toolbar + .get_or_insert_default() + .agent_review + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Code Actions", + description: "Whether to show code action buttons in the editor toolbar", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(toolbar) = &settings_content.editor.toolbar { + &toolbar.code_actions + } else { + &None + } + }, + pick_mut: |settings_content| { + &mut settings_content + .editor + .toolbar + .get_or_insert_default() + .code_actions + }, + }), + metadata: None, + files: USER, + }), + ]; + items.extend(language_settings_data()); + items + }, + }, + SettingsPage { + title: "Languages", + items: vec![ + SettingsPageItem::SectionHeader(LANGUAGES_SECTION_HEADER), + SettingsPageItem::SubPageLink(SubPageLink { + title: "JSON", + files: USER | LOCAL, + render: Arc::new(|this, window, cx| { + this.render_page_items(language_settings_data().iter(), window, cx) + .into_any_element() + }), + }), + SettingsPageItem::SubPageLink(SubPageLink { + title: "JSONC", + files: USER | LOCAL, + render: Arc::new(|this, window, cx| { + this.render_page_items(language_settings_data().iter(), window, cx) + .into_any_element() + }), + }), + SettingsPageItem::SubPageLink(SubPageLink { + title: "Rust", + files: USER | LOCAL, + render: Arc::new(|this, window, cx| { + this.render_page_items(language_settings_data().iter(), window, cx) + .into_any_element() + }), + }), + SettingsPageItem::SubPageLink(SubPageLink { + title: "Python", + files: USER | LOCAL, + render: Arc::new(|this, window, cx| { + this.render_page_items(language_settings_data().iter(), window, cx) + .into_any_element() + }), + }), + SettingsPageItem::SubPageLink(SubPageLink { + title: "TSX", + files: USER | LOCAL, + render: Arc::new(|this, window, cx| { + this.render_page_items(language_settings_data().iter(), window, cx) + .into_any_element() + }), + }), + ], + }, + SettingsPage { + title: "Workbench & Window", items: vec![ - SettingsPageItem::SectionHeader("Indentation"), + SettingsPageItem::SectionHeader("Status Bar"), SettingsPageItem::SettingItem(SettingItem { - title: "Tab Size", - description: "How many columns a tab should occupy", + title: "Active Language Button", + description: "Whether to show the active language button in the status bar", field: Box::new(SettingField { pick: |settings_content| { - &settings_content.project.all_languages.defaults.tab_size + if let Some(status_bar) = &settings_content.status_bar { + &status_bar.active_language_button + } else { + &None + } }, pick_mut: |settings_content| { - &mut settings_content.project.all_languages.defaults.tab_size + &mut settings_content + .status_bar + .get_or_insert_default() + .active_language_button }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Hard Tabs", - description: "Whether to indent lines using tab characters, as opposed to multiple spaces", + title: "Cursor Position Button", + description: "Whether to show the cursor position button in the status bar", field: Box::new(SettingField { pick: |settings_content| { - &settings_content.project.all_languages.defaults.hard_tabs + if let Some(status_bar) = &settings_content.status_bar { + &status_bar.cursor_position_button + } else { + &None + } }, pick_mut: |settings_content| { - &mut settings_content.project.all_languages.defaults.hard_tabs + &mut settings_content + .status_bar + .get_or_insert_default() + .cursor_position_button }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Auto Indent", - description: "Whether indentation should be adjusted based on the context whilst typing", + title: "Terminal Button", + description: "Whether to show the terminal button in the status bar", field: Box::new(SettingField { pick: |settings_content| { - &settings_content.project.all_languages.defaults.auto_indent + if let Some(terminal) = &settings_content.terminal { + &terminal.button + } else { + &None + } }, pick_mut: |settings_content| { - &mut settings_content.project.all_languages.defaults.auto_indent + &mut settings_content.terminal.get_or_insert_default().button }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Auto Indent On Paste", - description: "Whether indentation of pasted content should be adjusted based on the context", + title: "Diagnostics Button", + description: "Whether to show the project diagnostics button in the status bar", field: Box::new(SettingField { pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .auto_indent_on_paste + if let Some(diagnostics) = &settings_content.diagnostics { + &diagnostics.button + } else { + &None + } }, pick_mut: |settings_content| { - &mut settings_content - .project - .all_languages - .defaults - .auto_indent_on_paste + &mut settings_content.diagnostics.get_or_insert_default().button }, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("Wrapping"), SettingsPageItem::SettingItem(SettingItem { - title: "Preferred Line Length", - description: "The column at which to soft-wrap lines, for buffers where soft-wrap is enabled", + title: "Project Search Button", + description: "Whether to show the project search button in the status bar", field: Box::new(SettingField { pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .preferred_line_length + if let Some(search) = &settings_content.editor.search { + &search.button + } else { + &None + } }, pick_mut: |settings_content| { &mut settings_content - .project - .all_languages - .defaults - .preferred_line_length + .editor + .search + .get_or_insert_default() + .button }, }), metadata: None, + files: USER, }), + SettingsPageItem::SectionHeader("Tab Bar"), SettingsPageItem::SettingItem(SettingItem { - title: "Soft Wrap", - description: "How to soft-wrap long lines of text", + title: "Editor Tabs", + description: "Whether or not to show the tab bar in the editor", field: Box::new(SettingField { pick: |settings_content| { - &settings_content.project.all_languages.defaults.soft_wrap - }, - pick_mut: |settings_content| { - &mut settings_content.project.all_languages.defaults.soft_wrap - }, - }), - metadata: None, - }), - SettingsPageItem::SectionHeader("Search"), - SettingsPageItem::SettingItem(SettingItem { - title: "Search Wrap", - description: "Whether the editor search results will loop", - field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.search_wrap, - pick_mut: |settings_content| &mut settings_content.editor.search_wrap, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Seed Search Query From Cursor", - description: "When to populate a new search's query based on the text under the cursor", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content.editor.seed_search_query_from_cursor + if let Some(tab_bar) = &settings_content.tab_bar { + &tab_bar.show + } else { + &None + } }, pick_mut: |settings_content| { - &mut settings_content.editor.seed_search_query_from_cursor + &mut settings_content.tab_bar.get_or_insert_default().show }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Use Smartcase Search", - description: "Whether to use smartcase (i.e., case-sensitive) search", + title: "Show Navigation History Buttons", + description: "Whether or not to show the navigation history buttons in the tab bar", field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.use_smartcase_search, + pick: |settings_content| { + if let Some(tab_bar) = &settings_content.tab_bar { + &tab_bar.show_nav_history_buttons + } else { + &None + } + }, pick_mut: |settings_content| { - &mut settings_content.editor.use_smartcase_search + &mut settings_content + .tab_bar + .get_or_insert_default() + .show_nav_history_buttons }, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("Editor Behavior"), + SettingsPageItem::SectionHeader("Title Bar"), SettingsPageItem::SettingItem(SettingItem { - title: "Redact Private Values", - description: "Hide the values of variables in private files", + title: "Show Branch Icon", + description: "Whether to show the branch icon beside branch switcher in the titlebar", field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.redact_private_values, + pick: |settings_content| { + if let Some(title_bar) = &settings_content.title_bar { + &title_bar.show_branch_icon + } else { + &None + } + }, pick_mut: |settings_content| { - &mut settings_content.editor.redact_private_values + &mut settings_content + .title_bar + .get_or_insert_default() + .show_branch_icon }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Middle Click Paste", - description: "Whether to enable middle-click paste on Linux", + title: "Show Branch Name", + description: "Whether to show the branch name button in the titlebar", field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.middle_click_paste, + pick: |settings_content| { + if let Some(title_bar) = &settings_content.title_bar { + &title_bar.show_branch_name + } else { + &None + } + }, pick_mut: |settings_content| { - &mut settings_content.editor.middle_click_paste + &mut settings_content + .title_bar + .get_or_insert_default() + .show_branch_name }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Double Click In Multibuffer", - description: "What to do when multibuffer is double-clicked in some of its excerpts", + title: "Show Project Items", + description: "Whether to show the project host and name in the titlebar", field: Box::new(SettingField { pick: |settings_content| { - &settings_content.editor.double_click_in_multibuffer + if let Some(title_bar) = &settings_content.title_bar { + &title_bar.show_project_items + } else { + &None + } }, pick_mut: |settings_content| { - &mut settings_content.editor.double_click_in_multibuffer + &mut settings_content + .title_bar + .get_or_insert_default() + .show_project_items }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Go To Definition Fallback", - description: "Whether to follow-up empty go to definition responses from the language server", + title: "Show Onboarding Banner", + description: "Whether to show onboarding banners in the titlebar", field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.go_to_definition_fallback, + pick: |settings_content| { + if let Some(title_bar) = &settings_content.title_bar { + &title_bar.show_onboarding_banner + } else { + &None + } + }, pick_mut: |settings_content| { - &mut settings_content.editor.go_to_definition_fallback + &mut settings_content + .title_bar + .get_or_insert_default() + .show_onboarding_banner }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Expand Excerpt Lines", - description: "How many lines to expand the multibuffer excerpts by default", + title: "Show User Picture", + description: "Whether to show user picture in the titlebar", field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.expand_excerpt_lines, + pick: |settings_content| { + if let Some(title_bar) = &settings_content.title_bar { + &title_bar.show_user_picture + } else { + &None + } + }, pick_mut: |settings_content| { - &mut settings_content.editor.expand_excerpt_lines + &mut settings_content + .title_bar + .get_or_insert_default() + .show_user_picture }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Excerpt Context Lines", - description: "How many lines of context to provide in multibuffer excerpts by default", + title: "Show Sign In", + description: "Whether to show the sign in button in the titlebar", field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.excerpt_context_lines, + pick: |settings_content| { + if let Some(title_bar) = &settings_content.title_bar { + &title_bar.show_sign_in + } else { + &None + } + }, pick_mut: |settings_content| { - &mut settings_content.editor.excerpt_context_lines + &mut settings_content + .title_bar + .get_or_insert_default() + .show_sign_in }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Minimum Contrast For Highlights", - description: "The minimum APCA perceptual contrast to maintain when rendering text over highlight backgrounds", + title: "Show Menus", + description: "Whether to show the menus in the titlebar", field: Box::new(SettingField { pick: |settings_content| { - &settings_content.editor.minimum_contrast_for_highlights + if let Some(title_bar) = &settings_content.title_bar { + &title_bar.show_menus + } else { + &None + } }, pick_mut: |settings_content| { - &mut settings_content.editor.minimum_contrast_for_highlights + &mut settings_content + .title_bar + .get_or_insert_default() + .show_menus }, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("Scrolling"), + SettingsPageItem::SectionHeader("Tab Settings"), SettingsPageItem::SettingItem(SettingItem { - title: "Scroll Beyond Last Line", - description: "Whether the editor will scroll beyond the last line", + title: "Activate On Close", + description: "What to do after closing the current tab", field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.scroll_beyond_last_line, + pick: |settings_content| { + if let Some(tabs) = &settings_content.tabs { + &tabs.activate_on_close + } else { + &None + } + }, pick_mut: |settings_content| { - &mut settings_content.editor.scroll_beyond_last_line + &mut settings_content + .tabs + .get_or_insert_default() + .activate_on_close }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Vertical Scroll Margin", - description: "The number of lines to keep above/below the cursor when auto-scrolling", + title: "Tab Show Diagnostics", + description: "Which files containing diagnostic errors/warnings to mark in the tabs", field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.vertical_scroll_margin, + pick: |settings_content| { + if let Some(tabs) = &settings_content.tabs { + &tabs.show_diagnostics + } else { + &None + } + }, pick_mut: |settings_content| { - &mut settings_content.editor.vertical_scroll_margin + &mut settings_content + .tabs + .get_or_insert_default() + .show_diagnostics }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Horizontal Scroll Margin", - description: "The number of characters to keep on either side when scrolling with the mouse", + title: "Show Close Button", + description: "Controls the appearance behavior of the tab's close button", field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.horizontal_scroll_margin, + pick: |settings_content| { + if let Some(tabs) = &settings_content.tabs { + &tabs.show_close_button + } else { + &None + } + }, pick_mut: |settings_content| { - &mut settings_content.editor.horizontal_scroll_margin + &mut settings_content + .tabs + .get_or_insert_default() + .show_close_button }, }), metadata: None, + files: USER, }), + SettingsPageItem::SectionHeader("Preview Tabs"), SettingsPageItem::SettingItem(SettingItem { - title: "Scroll Sensitivity", - description: "Scroll sensitivity multiplier for both horizontal and vertical scrolling", + title: "Preview Tabs Enabled", + description: "Whether to show opened editors as preview tabs", field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.scroll_sensitivity, + pick: |settings_content| { + if let Some(preview_tabs) = &settings_content.preview_tabs { + &preview_tabs.enabled + } else { + &None + } + }, pick_mut: |settings_content| { - &mut settings_content.editor.scroll_sensitivity + &mut settings_content + .preview_tabs + .get_or_insert_default() + .enabled }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Fast Scroll Sensitivity", - description: "Fast Scroll sensitivity multiplier for both horizontal and vertical scrolling", + title: "Enable Preview From File Finder", + description: "Whether to open tabs in preview mode when selected from the file finder", field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.fast_scroll_sensitivity, + pick: |settings_content| { + if let Some(preview_tabs) = &settings_content.preview_tabs { + &preview_tabs.enable_preview_from_file_finder + } else { + &None + } + }, pick_mut: |settings_content| { - &mut settings_content.editor.fast_scroll_sensitivity + &mut settings_content + .preview_tabs + .get_or_insert_default() + .enable_preview_from_file_finder }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Autoscroll On Clicks", - description: "Whether to scroll when clicking near the edge of the visible text area", + title: "Enable Preview From Code Navigation", + description: "Whether a preview tab gets replaced when code navigation is used to navigate away from the tab", field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.autoscroll_on_clicks, + pick: |settings_content| { + if let Some(preview_tabs) = &settings_content.preview_tabs { + &preview_tabs.enable_preview_from_code_navigation + } else { + &None + } + }, pick_mut: |settings_content| { - &mut settings_content.editor.autoscroll_on_clicks + &mut settings_content + .preview_tabs + .get_or_insert_default() + .enable_preview_from_code_navigation }, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("Auto Actions"), + SettingsPageItem::SectionHeader("Search Settings"), SettingsPageItem::SettingItem(SettingItem { - title: "Use Autoclose", - description: "Whether to automatically type closing characters for you", + title: "Whole Word", + description: "Whether to search for whole words by default", field: Box::new(SettingField { pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .use_autoclose + if let Some(search) = &settings_content.editor.search { + &search.whole_word + } else { + &None + } }, pick_mut: |settings_content| { &mut settings_content - .project - .all_languages - .defaults - .use_autoclose + .editor + .search + .get_or_insert_default() + .whole_word }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Use Auto Surround", - description: "Whether to automatically surround text with characters for you", + title: "Case Sensitive", + description: "Whether to search case-sensitively by default", field: Box::new(SettingField { pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .use_auto_surround + if let Some(search) = &settings_content.editor.search { + &search.case_sensitive + } else { + &None + } }, pick_mut: |settings_content| { &mut settings_content - .project - .all_languages - .defaults - .use_auto_surround + .editor + .search + .get_or_insert_default() + .case_sensitive }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Use On Type Format", - description: "Whether to use additional LSP queries to format the code after every trigger symbol input", + title: "Include Ignored", + description: "Whether to include ignored files in search results by default", field: Box::new(SettingField { pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .use_on_type_format + if let Some(search) = &settings_content.editor.search { + &search.include_ignored + } else { + &None + } }, pick_mut: |settings_content| { &mut settings_content - .project - .all_languages - .defaults - .use_on_type_format + .editor + .search + .get_or_insert_default() + .include_ignored }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Always Treat Brackets As Autoclosed", - description: "Controls how the editor handles the autoclosed characters", + title: "Regex", + description: "Whether to use regex search by default", field: Box::new(SettingField { pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .always_treat_brackets_as_autoclosed + if let Some(search) = &settings_content.editor.search { + &search.regex + } else { + &None + } }, pick_mut: |settings_content| { - &mut settings_content - .project - .all_languages - .defaults - .always_treat_brackets_as_autoclosed + &mut settings_content.editor.search.get_or_insert_default().regex }, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("Formatting"), + SettingsPageItem::SectionHeader("File Finder"), SettingsPageItem::SettingItem(SettingItem { - title: "Remove Trailing Whitespace On Save", - description: "Whether or not to remove any trailing whitespace from lines of a buffer before saving it", + title: "File Icons", + description: "Whether to show file icons in the file finder", field: Box::new(SettingField { pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .remove_trailing_whitespace_on_save + if let Some(file_finder) = &settings_content.file_finder { + &file_finder.file_icons + } else { + &None + } }, pick_mut: |settings_content| { &mut settings_content - .project - .all_languages - .defaults - .remove_trailing_whitespace_on_save + .file_finder + .get_or_insert_default() + .file_icons }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Ensure Final Newline On Save", - description: "Whether or not to ensure there's a single newline at the end of a buffer when saving it", + title: "Modal Max Width", + description: "Determines how much space the file finder can take up in relation to the available window width", field: Box::new(SettingField { pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .ensure_final_newline_on_save + if let Some(file_finder) = &settings_content.file_finder { + &file_finder.modal_max_width + } else { + &None + } }, pick_mut: |settings_content| { &mut settings_content - .project - .all_languages - .defaults - .ensure_final_newline_on_save + .file_finder + .get_or_insert_default() + .modal_max_width }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Extend Comment On Newline", - description: "Whether to start a new line with a comment when a previous line is a comment as well", + title: "Skip Focus For Active In Search", + description: "Whether the file finder should skip focus for the active file in search results", field: Box::new(SettingField { pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .extend_comment_on_newline + if let Some(file_finder) = &settings_content.file_finder { + &file_finder.skip_focus_for_active_in_search + } else { + &None + } }, pick_mut: |settings_content| { &mut settings_content - .project - .all_languages - .defaults - .extend_comment_on_newline + .file_finder + .get_or_insert_default() + .skip_focus_for_active_in_search }, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("Language Server Completions"), SettingsPageItem::SettingItem(SettingItem { - title: "Show Completions On Input", - description: "Whether to pop the completions menu while typing in an editor without explicitly requesting it", + title: "Git Status", + description: "Whether to show the git status in the file finder", field: Box::new(SettingField { pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .show_completions_on_input + if let Some(file_finder) = &settings_content.file_finder { + &file_finder.git_status + } else { + &None + } }, pick_mut: |settings_content| { &mut settings_content - .project - .all_languages - .defaults - .show_completions_on_input + .file_finder + .get_or_insert_default() + .git_status }, }), metadata: None, + 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, + // }), + ], + }, + SettingsPage { + title: "Panels", + items: vec![ + SettingsPageItem::SectionHeader("Project Panel"), SettingsPageItem::SettingItem(SettingItem { - title: "Show Completion Documentation", - description: "Whether to display inline and alongside documentation for items in the completions menu", + title: "Project Panel Button", + description: "Whether to show the project panel button in the status bar", field: Box::new(SettingField { pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .show_completion_documentation + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.button + } else { + &None + } }, pick_mut: |settings_content| { &mut settings_content - .project - .all_languages - .defaults - .show_completion_documentation - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Auto Signature Help", - description: "Whether to automatically show a signature help pop-up or not", - field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.auto_signature_help, - pick_mut: |settings_content| { - &mut settings_content.editor.auto_signature_help + .project_panel + .get_or_insert_default() + .button }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Show Signature Help After Edits", - description: "Whether to show the signature help pop-up after completions or bracket pairs inserted", + title: "Project Panel Dock", + description: "Where to dock the project panel", field: Box::new(SettingField { pick: |settings_content| { - &settings_content.editor.show_signature_help_after_edits - }, - pick_mut: |settings_content| { - &mut settings_content.editor.show_signature_help_after_edits - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Snippet Sort Order", - description: "Determines how snippets are sorted relative to other completion items", - field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.snippet_sort_order, - pick_mut: |settings_content| { - &mut settings_content.editor.snippet_sort_order - }, - }), - metadata: None, - }), - SettingsPageItem::SectionHeader("Hover"), - SettingsPageItem::SettingItem(SettingItem { - title: "Hover Popover Enabled", - description: "Whether to show the informational hover box when moving the mouse over symbols in the editor", - field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.hover_popover_enabled, - pick_mut: |settings_content| { - &mut settings_content.editor.hover_popover_enabled - }, - }), - metadata: None, - }), - // todo(settings ui): add units to this Number Field - SettingsPageItem::SettingItem(SettingItem { - title: "Hover Popover Delay", - description: "Time to wait in milliseconds before showing the informational hover box", - field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.hover_popover_delay, - pick_mut: |settings_content| { - &mut settings_content.editor.hover_popover_delay + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.dock + } else { + &None + } }, - }), - metadata: None, - }), - SettingsPageItem::SectionHeader("Code Actions"), - SettingsPageItem::SettingItem(SettingItem { - title: "Inline Code Actions", - description: "Whether to show code action button at start of buffer line", - field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.inline_code_actions, pick_mut: |settings_content| { - &mut settings_content.editor.inline_code_actions + &mut settings_content.project_panel.get_or_insert_default().dock }, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("Selection"), SettingsPageItem::SettingItem(SettingItem { - title: "Drag And Drop Selection", - description: "Whether to enable drag and drop selection", + title: "Project Panel Default Width", + description: "Default width of the project panel in pixels", field: Box::new(SettingField { pick: |settings_content| { - if let Some(drag_and_drop) = - &settings_content.editor.drag_and_drop_selection - { - &drag_and_drop.enabled + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.default_width } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .drag_and_drop_selection + .project_panel .get_or_insert_default() - .enabled + .default_width }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Drag And Drop Selection Delay", - description: "Delay in milliseconds before drag and drop selection starts", + title: "Hide .gitignore", + description: "Whether to hide the gitignore entries in the project panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(drag_and_drop) = - &settings_content.editor.drag_and_drop_selection - { - &drag_and_drop.delay + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.hide_gitignore } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .drag_and_drop_selection + .project_panel .get_or_insert_default() - .delay + .hide_gitignore }, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("Gutter"), SettingsPageItem::SettingItem(SettingItem { - title: "Show Line Numbers", - description: "Whether to show line numbers in the gutter", + title: "Entry Spacing", + description: "Spacing between worktree entries in the project panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(gutter) = &settings_content.editor.gutter { - &gutter.line_numbers + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.entry_spacing } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .gutter + .project_panel .get_or_insert_default() - .line_numbers - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Relative Line Numbers", - description: "Whether the line numbers on editors gutter are relative or not", - field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.relative_line_numbers, - pick_mut: |settings_content| { - &mut settings_content.editor.relative_line_numbers + .entry_spacing }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Show Runnables", - description: "Whether to show runnable buttons in the gutter", + title: "File Icons", + description: "Whether to show folder icons or chevrons for directories in the project panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(gutter) = &settings_content.editor.gutter { - &gutter.runnables + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.file_icons } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .gutter + .project_panel .get_or_insert_default() - .runnables + .file_icons }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Show Breakpoints", - description: "Whether to show breakpoints in the gutter", + title: "Folder Icons", + description: "Whether to show folder icons or chevrons for directories in the project panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(gutter) = &settings_content.editor.gutter { - &gutter.breakpoints + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.folder_icons } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .gutter + .project_panel .get_or_insert_default() - .breakpoints + .folder_icons }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Show Folds", - description: "Whether to show code folding controls in the gutter", + title: "Git Status", + description: "Whether to show the git status in the project panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(gutter) = &settings_content.editor.gutter { - &gutter.folds + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.git_status } else { &None } }, pick_mut: |settings_content| { - &mut settings_content.editor.gutter.get_or_insert_default().folds + &mut settings_content + .project_panel + .get_or_insert_default() + .git_status }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Min Line Number Digits", - description: "Minimum number of characters to reserve space for in the gutter.", + title: "Indent Size", + description: "Amount of indentation for nested items", field: Box::new(SettingField { pick: |settings_content| { - if let Some(gutter) = &settings_content.editor.gutter { - &gutter.min_line_number_digits + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.indent_size } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .gutter + .project_panel .get_or_insert_default() - .min_line_number_digits + .indent_size }, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("Scrollbar"), SettingsPageItem::SettingItem(SettingItem { - title: "Show", - description: "When to show the scrollbar in the editor", + title: "Auto Reveal Entries", + description: "Whether to reveal it in the project panel automatically when a corresponding project entry becomes active", field: Box::new(SettingField { pick: |settings_content| { - if let Some(scrollbar) = &settings_content.editor.scrollbar { - &scrollbar.show + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.auto_reveal_entries } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .scrollbar + .project_panel .get_or_insert_default() - .show + .auto_reveal_entries }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Cursors", - description: "Whether to show cursor positions in the scrollbar", + title: "Starts Open", + description: "Whether the project panel should open on startup", field: Box::new(SettingField { pick: |settings_content| { - if let Some(scrollbar) = &settings_content.editor.scrollbar { - &scrollbar.cursors + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.starts_open } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .scrollbar + .project_panel .get_or_insert_default() - .cursors + .starts_open }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Git Diff", - description: "Whether to show git diff indicators in the scrollbar", + title: "Auto Fold Directories", + description: "Whether to fold directories automatically and show compact folders when a directory has only one subdirectory inside", field: Box::new(SettingField { pick: |settings_content| { - if let Some(scrollbar) = &settings_content.editor.scrollbar { - &scrollbar.git_diff + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.auto_fold_dirs } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .scrollbar + .project_panel .get_or_insert_default() - .git_diff + .auto_fold_dirs }, }), metadata: None, + files: USER, }), - SettingsPageItem::SettingItem(SettingItem { - title: "Search Results", - description: "Whether to show buffer search result indicators in the scrollbar", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(scrollbar) = &settings_content.editor.scrollbar { - &scrollbar.search_results - } else { - &None - } - }, + // 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: "Show Diagnostics", + description: "Which files containing diagnostic errors/warnings to mark in the project panel", + field: Box::new(SettingField { + pick: |settings_content| { + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.show_diagnostics + } else { + &None + } + }, pick_mut: |settings_content| { &mut settings_content - .editor - .scrollbar + .project_panel .get_or_insert_default() - .search_results + .show_diagnostics }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Selected Text", - description: "Whether to show selected text occurrences in the scrollbar", + title: "Sticky Scroll", + description: "Whether to stick parent directories at top of the project panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(scrollbar) = &settings_content.editor.scrollbar { - &scrollbar.selected_text + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.sticky_scroll } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .scrollbar + .project_panel .get_or_insert_default() - .selected_text + .sticky_scroll }, }), 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 { - title: "Selected Symbol", - description: "Whether to show selected symbol occurrences in the scrollbar", + title: "Drag and Drop", + description: "Whether to enable drag-and-drop operations in the project panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(scrollbar) = &settings_content.editor.scrollbar { - &scrollbar.selected_symbol + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.drag_and_drop } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .scrollbar + .project_panel .get_or_insert_default() - .selected_symbol + .drag_and_drop }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Diagnostics", - description: "Which diagnostic indicators to show in the scrollbar", + title: "Hide Root", + description: "Whether to hide the root entry when only one folder is open in the window", field: Box::new(SettingField { pick: |settings_content| { - if let Some(scrollbar) = &settings_content.editor.scrollbar { - &scrollbar.diagnostics + if let Some(project_panel) = &settings_content.project_panel { + &project_panel.hide_root } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .scrollbar + .project_panel .get_or_insert_default() - .diagnostics + .hide_root }, }), metadata: None, + files: USER, }), + SettingsPageItem::SectionHeader("Terminal Panel"), SettingsPageItem::SettingItem(SettingItem { - title: "Horizontal Scrollbar", - description: "When false, forcefully disables the horizontal scrollbar", + title: "Terminal Dock", + description: "Where to dock the terminal panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(scrollbar) = &settings_content.editor.scrollbar { - if let Some(axes) = &scrollbar.axes { - &axes.horizontal - } else { - &None - } + if let Some(terminal) = &settings_content.terminal { + &terminal.dock } else { &None } }, pick_mut: |settings_content| { - &mut settings_content - .editor - .scrollbar - .get_or_insert_default() - .axes - .get_or_insert_default() - .horizontal + &mut settings_content.terminal.get_or_insert_default().dock }, }), metadata: None, + files: USER, }), + SettingsPageItem::SectionHeader("Outline Panel"), SettingsPageItem::SettingItem(SettingItem { - title: "Vertical Scrollbar", - description: "When false, forcefully disables the vertical scrollbar", + title: "Outline Panel Button", + description: "Whether to show the outline panel button in the status bar", field: Box::new(SettingField { pick: |settings_content| { - if let Some(scrollbar) = &settings_content.editor.scrollbar { - if let Some(axes) = &scrollbar.axes { - &axes.vertical - } else { - &None - } + if let Some(outline_panel) = &settings_content.outline_panel { + &outline_panel.button } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .scrollbar - .get_or_insert_default() - .axes + .outline_panel .get_or_insert_default() - .vertical + .button }, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("Minimap"), SettingsPageItem::SettingItem(SettingItem { - title: "Show", - description: "When to show the minimap in the editor", + title: "Outline Panel Dock", + description: "Where to dock the outline panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(minimap) = &settings_content.editor.minimap { - &minimap.show + if let Some(outline_panel) = &settings_content.outline_panel { + &outline_panel.dock } else { &None } }, pick_mut: |settings_content| { - &mut settings_content.editor.minimap.get_or_insert_default().show + &mut settings_content.outline_panel.get_or_insert_default().dock }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Display In", - description: "Where to show the minimap in the editor", + title: "Outline Panel Default Width", + description: "Default width of the outline panel in pixels", field: Box::new(SettingField { pick: |settings_content| { - if let Some(minimap) = &settings_content.editor.minimap { - &minimap.display_in + if let Some(outline_panel) = &settings_content.outline_panel { + &outline_panel.default_width } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .minimap + .outline_panel .get_or_insert_default() - .display_in + .default_width }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Thumb", - description: "When to show the minimap thumb", + title: "File Icons", + description: "Whether to show file icons in the outline panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(minimap) = &settings_content.editor.minimap { - &minimap.thumb + if let Some(outline_panel) = &settings_content.outline_panel { + &outline_panel.file_icons } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .minimap + .outline_panel .get_or_insert_default() - .thumb + .file_icons }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Thumb Border", - description: "Border style for the minimap's scrollbar thumb", + title: "Folder Icons", + description: "Whether to show folder icons or chevrons for directories in the outline panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(minimap) = &settings_content.editor.minimap { - &minimap.thumb_border + if let Some(outline_panel) = &settings_content.outline_panel { + &outline_panel.folder_icons } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .minimap + .outline_panel .get_or_insert_default() - .thumb_border + .folder_icons }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Current Line Highlight", - description: "How to highlight the current line in the minimap", + title: "Git Status", + description: "Whether to show the git status in the outline panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(minimap) = &settings_content.editor.minimap - && minimap.current_line_highlight.is_some() - { - &minimap.current_line_highlight + if let Some(outline_panel) = &settings_content.outline_panel { + &outline_panel.git_status } else { - &settings_content.editor.current_line_highlight + &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .minimap + .outline_panel .get_or_insert_default() - .current_line_highlight + .git_status }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Max Width Columns", - description: "Maximum number of columns to display in the minimap", + title: "Indent Size", + description: "Amount of indentation for nested items", field: Box::new(SettingField { pick: |settings_content| { - if let Some(minimap) = &settings_content.editor.minimap { - &minimap.max_width_columns + if let Some(outline_panel) = &settings_content.outline_panel { + &outline_panel.indent_size } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .minimap + .outline_panel .get_or_insert_default() - .max_width_columns + .indent_size }, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("Tabs"), SettingsPageItem::SettingItem(SettingItem { - title: "Show Tab Bar", - description: "Whether or not to show the tab bar in the editor", + title: "Auto Reveal Entries", + description: "Whether to reveal when a corresponding outline entry becomes active", field: Box::new(SettingField { pick: |settings_content| { - if let Some(tab_bar) = &settings_content.tab_bar { - &tab_bar.show + if let Some(outline_panel) = &settings_content.outline_panel { + &outline_panel.auto_reveal_entries } else { &None } }, pick_mut: |settings_content| { - &mut settings_content.tab_bar.get_or_insert_default().show + &mut settings_content + .outline_panel + .get_or_insert_default() + .auto_reveal_entries }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Show Git Status In Tabs", - description: "Whether to show the Git file status on a tab item", + title: "Auto Fold Directories", + description: "Whether to fold directories automatically when a directory has only one directory inside", field: Box::new(SettingField { pick: |settings_content| { - if let Some(tabs) = &settings_content.tabs { - &tabs.git_status + if let Some(outline_panel) = &settings_content.outline_panel { + &outline_panel.auto_fold_dirs } else { &None } }, pick_mut: |settings_content| { - &mut settings_content.tabs.get_or_insert_default().git_status + &mut settings_content + .outline_panel + .get_or_insert_default() + .auto_fold_dirs }, }), 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::SectionHeader("Git Panel"), SettingsPageItem::SettingItem(SettingItem { - title: "Show File Icons In Tabs", - description: "Whether to show the file icon for a tab", + title: "Button", + description: "Whether to show the git panel button in the status bar", field: Box::new(SettingField { pick: |settings_content| { - if let Some(tabs) = &settings_content.tabs { - &tabs.file_icons + if let Some(git_panel) = &settings_content.git_panel { + &git_panel.button } else { &None } }, pick_mut: |settings_content| { - &mut settings_content.tabs.get_or_insert_default().file_icons + &mut settings_content.git_panel.get_or_insert_default().button }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Tab Close Position", - description: "Position of the close button in a tab", + title: "Dock", + description: "Where to dock the git panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(tabs) = &settings_content.tabs { - &tabs.close_position + if let Some(git_panel) = &settings_content.git_panel { + &git_panel.dock } else { &None } }, pick_mut: |settings_content| { - &mut settings_content.tabs.get_or_insert_default().close_position + &mut settings_content.git_panel.get_or_insert_default().dock }, }), metadata: None, + 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::SectionHeader("Toolbar"), SettingsPageItem::SettingItem(SettingItem { - title: "Breadcrumbs", - description: "Whether to show breadcrumbs", + title: "Default Width", + description: "Default width of the git panel in pixels", field: Box::new(SettingField { pick: |settings_content| { - if let Some(toolbar) = &settings_content.editor.toolbar { - &toolbar.breadcrumbs + if let Some(git_panel) = &settings_content.git_panel { + &git_panel.default_width } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .toolbar + .git_panel .get_or_insert_default() - .breadcrumbs + .default_width }, }), metadata: None, + files: USER, }), + SettingsPageItem::SectionHeader("Notification Panel"), SettingsPageItem::SettingItem(SettingItem { - title: "Quick Actions", - description: "Whether to show quick action buttons (e.g., search, selection, editor controls, etc.)", + title: "Notification Panel Button", + description: "Whether to show the notification panel button in the status bar", field: Box::new(SettingField { pick: |settings_content| { - if let Some(toolbar) = &settings_content.editor.toolbar { - &toolbar.quick_actions + if let Some(notification_panel) = &settings_content.notification_panel { + ¬ification_panel.button } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .toolbar + .notification_panel .get_or_insert_default() - .quick_actions + .button }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Selections Menu", - description: "Whether to show the selections menu in the editor toolbar", + title: "Notification Panel Dock", + description: "Where to dock the notification panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(toolbar) = &settings_content.editor.toolbar { - &toolbar.selections_menu + if let Some(notification_panel) = &settings_content.notification_panel { + ¬ification_panel.dock } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .toolbar + .notification_panel .get_or_insert_default() - .selections_menu + .dock }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Agent Review", - description: "Whether to show agent review buttons in the editor toolbar", + title: "Notification Panel Default Width", + description: "Default width of the notification panel in pixels", field: Box::new(SettingField { pick: |settings_content| { - if let Some(toolbar) = &settings_content.editor.toolbar { - &toolbar.agent_review + if let Some(notification_panel) = &settings_content.notification_panel { + ¬ification_panel.default_width } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .toolbar + .notification_panel .get_or_insert_default() - .agent_review + .default_width }, }), metadata: None, + files: USER, }), + SettingsPageItem::SectionHeader("Collaboration Panel"), SettingsPageItem::SettingItem(SettingItem { - title: "Code Actions", - description: "Whether to show code action buttons in the editor toolbar", + title: "Collaboration Panel Button", + description: "Whether to show the collaboration panel button in the status bar", field: Box::new(SettingField { pick: |settings_content| { - if let Some(toolbar) = &settings_content.editor.toolbar { - &toolbar.code_actions + if let Some(collaboration_panel) = &settings_content.collaboration_panel + { + &collaboration_panel.button } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .toolbar + .collaboration_panel .get_or_insert_default() - .code_actions + .button }, }), metadata: None, + files: USER, }), - ], - }, - SettingsPage { - title: "Languages & Frameworks", - items: { - let mut items = vec![ - SettingsPageItem::SectionHeader(LANGUAGES_SECTION_HEADER), - SettingsPageItem::SubPageLink(SubPageLink { - title: "JSON", - render: Arc::new(|this, window, cx| { - this.render_page_items(language_settings_data().iter(), window, cx) - .into_any_element() - }), - }), - SettingsPageItem::SubPageLink(SubPageLink { - title: "JSONC", - render: Arc::new(|this, window, cx| { - this.render_page_items(language_settings_data().iter(), window, cx) - .into_any_element() - }), - }), - SettingsPageItem::SubPageLink(SubPageLink { - title: "Rust", - render: Arc::new(|this, window, cx| { - this.render_page_items(language_settings_data().iter(), window, cx) - .into_any_element() - }), - }), - SettingsPageItem::SubPageLink(SubPageLink { - title: "Python", - render: Arc::new(|this, window, cx| { - this.render_page_items(language_settings_data().iter(), window, cx) - .into_any_element() - }), - }), - SettingsPageItem::SubPageLink(SubPageLink { - title: "TSX", - render: Arc::new(|this, window, cx| { - this.render_page_items(language_settings_data().iter(), window, cx) - .into_any_element() - }), - }), - ]; - - items.push(SettingsPageItem::SectionHeader("Default Language Settings")); - items.extend(language_settings_data()); - - items - }, - }, - SettingsPage { - title: "Workbench & Window", - items: vec![ - SettingsPageItem::SectionHeader("Status Bar"), SettingsPageItem::SettingItem(SettingItem { - title: "Active Language Button", - description: "Whether to show the active language button in the status bar", + title: "Collaboration Panel Dock", + description: "Where to dock the collaboration panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(status_bar) = &settings_content.status_bar { - &status_bar.active_language_button + if let Some(collaboration_panel) = &settings_content.collaboration_panel + { + &collaboration_panel.dock } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .status_bar + .collaboration_panel .get_or_insert_default() - .active_language_button + .dock }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Cursor Position Button", - description: "Whether to show the cursor position button in the status bar", + title: "Collaboration Panel Default Width", + description: "Default width of the collaboration panel in pixels", field: Box::new(SettingField { pick: |settings_content| { - if let Some(status_bar) = &settings_content.status_bar { - &status_bar.cursor_position_button + if let Some(collaboration_panel) = &settings_content.collaboration_panel + { + &collaboration_panel.default_width } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .status_bar + .collaboration_panel .get_or_insert_default() - .cursor_position_button + .default_width }, }), metadata: None, + files: USER, }), + ], + }, + SettingsPage { + title: "Version Control", + items: vec![ + SettingsPageItem::SectionHeader("Git"), SettingsPageItem::SettingItem(SettingItem { - title: "Terminal Button", - description: "Whether to show the terminal button in the status bar", + title: "Git Gutter", + description: "Control whether git status is shown in the editor's gutter", field: Box::new(SettingField { pick: |settings_content| { - if let Some(terminal) = &settings_content.terminal { - &terminal.button + if let Some(git) = &settings_content.git { + &git.git_gutter } else { &None } }, pick_mut: |settings_content| { - &mut settings_content.terminal.get_or_insert_default().button + &mut settings_content.git.get_or_insert_default().git_gutter }, }), metadata: None, + files: USER, }), + // todo(settings_ui): Figure out the right default for this value in default.json SettingsPageItem::SettingItem(SettingItem { - title: "Diagnostics Button", - description: "Whether to show the project diagnostics button in the status bar", + title: "Gutter Debounce", + description: "Debounce threshold in milliseconds after which changes are reflected in the git gutter", field: Box::new(SettingField { pick: |settings_content| { - if let Some(diagnostics) = &settings_content.diagnostics { - &diagnostics.button + if let Some(git) = &settings_content.git { + &git.gutter_debounce } else { &None } }, pick_mut: |settings_content| { - &mut settings_content.diagnostics.get_or_insert_default().button + &mut settings_content.git.get_or_insert_default().gutter_debounce }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Project Search Button", - description: "Whether to show the project search button in the status bar", + title: "Inline Git Blame", + description: "Whether or not to show git blame data inline in the currently focused line", field: Box::new(SettingField { pick: |settings_content| { - if let Some(search) = &settings_content.editor.search { - &search.button + if let Some(git) = &settings_content.git { + if let Some(inline_blame) = &git.inline_blame { + &inline_blame.enabled + } else { + &None + } } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .search + .git .get_or_insert_default() - .button - }, - }), - metadata: None, - }), - SettingsPageItem::SectionHeader("Tab Bar"), - SettingsPageItem::SettingItem(SettingItem { - title: "Editor Tabs", - description: "Whether or not to show the tab bar in the editor", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(tab_bar) = &settings_content.tab_bar { - &tab_bar.show - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.tab_bar.get_or_insert_default().show + .inline_blame + .get_or_insert_default() + .enabled }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Show Navigation History Buttons", - description: "Whether or not to show the navigation history buttons in the tab bar", + title: "Inline Git Blame Delay", + description: "The delay after which the inline blame information is shown", field: Box::new(SettingField { pick: |settings_content| { - if let Some(tab_bar) = &settings_content.tab_bar { - &tab_bar.show_nav_history_buttons + if let Some(git) = &settings_content.git { + if let Some(inline_blame) = &git.inline_blame { + &inline_blame.delay_ms + } else { + &None + } } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .tab_bar + .git .get_or_insert_default() - .show_nav_history_buttons + .inline_blame + .get_or_insert_default() + .delay_ms }, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("Title Bar"), SettingsPageItem::SettingItem(SettingItem { - title: "Show Branch Icon", - description: "Whether to show the branch icon beside branch switcher in the titlebar", + title: "Inline Git Blame Padding", + description: "Padding between the end of the source line and the start of the inline blame in columns", field: Box::new(SettingField { pick: |settings_content| { - if let Some(title_bar) = &settings_content.title_bar { - &title_bar.show_branch_icon + if let Some(git) = &settings_content.git { + if let Some(inline_blame) = &git.inline_blame { + &inline_blame.padding + } else { + &None + } } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .title_bar + .git .get_or_insert_default() - .show_branch_icon + .inline_blame + .get_or_insert_default() + .padding }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Show Branch Name", - description: "Whether to show the branch name button in the titlebar", + title: "Inline Git Blame Min Column", + description: "The minimum column number to show the inline blame information at", field: Box::new(SettingField { pick: |settings_content| { - if let Some(title_bar) = &settings_content.title_bar { - &title_bar.show_branch_name + if let Some(git) = &settings_content.git { + if let Some(inline_blame) = &git.inline_blame { + &inline_blame.min_column + } else { + &None + } } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .title_bar + .git .get_or_insert_default() - .show_branch_name + .inline_blame + .get_or_insert_default() + .min_column }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Show Project Items", - description: "Whether to show the project host and name in the titlebar", + title: "Show Commit Summary", + description: "Whether to show commit summary as part of the inline blame", field: Box::new(SettingField { pick: |settings_content| { - if let Some(title_bar) = &settings_content.title_bar { - &title_bar.show_project_items + if let Some(git) = &settings_content.git { + if let Some(inline_blame) = &git.inline_blame { + &inline_blame.show_commit_summary + } else { + &None + } } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .title_bar + .git .get_or_insert_default() - .show_project_items + .inline_blame + .get_or_insert_default() + .show_commit_summary }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Show Onboarding Banner", - description: "Whether to show onboarding banners in the titlebar", + title: "Show Avatar", + description: "Whether to show the avatar of the author of the commit", field: Box::new(SettingField { pick: |settings_content| { - if let Some(title_bar) = &settings_content.title_bar { - &title_bar.show_onboarding_banner + if let Some(git) = &settings_content.git { + if let Some(blame) = &git.blame { + &blame.show_avatar + } else { + &None + } } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .title_bar + .git .get_or_insert_default() - .show_onboarding_banner + .blame + .get_or_insert_default() + .show_avatar }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Show User Picture", - description: "Whether to show user picture in the titlebar", + title: "Show Author Name In Branch Picker", + description: "Whether to show author name as part of the commit information in branch picker", field: Box::new(SettingField { pick: |settings_content| { - if let Some(title_bar) = &settings_content.title_bar { - &title_bar.show_user_picture + if let Some(git) = &settings_content.git { + if let Some(branch_picker) = &git.branch_picker { + &branch_picker.show_author_name + } else { + &None + } } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .title_bar + .git .get_or_insert_default() - .show_user_picture + .branch_picker + .get_or_insert_default() + .show_author_name }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Show Sign In", - description: "Whether to show the sign in button in the titlebar", + title: "Hunk Style", + description: "How git hunks are displayed visually in the editor", field: Box::new(SettingField { pick: |settings_content| { - if let Some(title_bar) = &settings_content.title_bar { - &title_bar.show_sign_in + if let Some(git) = &settings_content.git { + &git.hunk_style } else { &None } }, pick_mut: |settings_content| { - &mut settings_content - .title_bar - .get_or_insert_default() - .show_sign_in + &mut settings_content.git.get_or_insert_default().hunk_style }, }), metadata: None, + files: USER, }), - SettingsPageItem::SettingItem(SettingItem { - title: "Show Menus", - description: "Whether to show the menus in the titlebar", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(title_bar) = &settings_content.title_bar { - &title_bar.show_menus - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .title_bar - .get_or_insert_default() - .show_menus - }, + ], + }, + SettingsPage { + title: "System & Network", + 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: "Server URL", + description: "The URL of the Zed server to connect to", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.server_url, + pick_mut: |settings_content| &mut settings_content.server_url, + }), + metadata: Some(Box::new(SettingsFieldMetadata { + placeholder: Some("https://zed.dev"), + })), + files: USER, + }), + SettingsPageItem::SectionHeader("System"), + SettingsPageItem::SettingItem(SettingItem { + title: "Auto Update", + description: "Whether or not to automatically check for updates", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.auto_update, + pick_mut: |settings_content| &mut settings_content.auto_update, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("Tab Settings"), + ], + }, + SettingsPage { + title: "Diagnostics & Errors", + items: vec![ + SettingsPageItem::SectionHeader("Filtering"), SettingsPageItem::SettingItem(SettingItem { - title: "Activate On Close", - description: "What to do after closing the current tab", + title: "Max Severity", + description: "Which level to use to filter out diagnostics displayed in the editor", + field: Box::new(SettingField { + pick: |settings_content| &settings_content.editor.diagnostics_max_severity, + pick_mut: |settings_content| { + &mut settings_content.editor.diagnostics_max_severity + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Include Warnings", + description: "Whether to show warnings or not by default", field: Box::new(SettingField { pick: |settings_content| { - if let Some(tabs) = &settings_content.tabs { - &tabs.activate_on_close + if let Some(diagnostics) = &settings_content.diagnostics { + &diagnostics.include_warnings } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .tabs + .diagnostics .get_or_insert_default() - .activate_on_close + .include_warnings }, }), metadata: None, + files: USER, }), + SettingsPageItem::SectionHeader("Inline"), SettingsPageItem::SettingItem(SettingItem { - title: "Tab Show Diagnostics", - description: "Which files containing diagnostic errors/warnings to mark in the tabs", + title: "Inline Diagnostics Enabled", + description: "Whether to show diagnostics inline or not", field: Box::new(SettingField { pick: |settings_content| { - if let Some(tabs) = &settings_content.tabs { - &tabs.show_diagnostics + if let Some(diagnostics) = &settings_content.diagnostics { + if let Some(inline) = &diagnostics.inline { + &inline.enabled + } else { + &None + } } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .tabs + .diagnostics .get_or_insert_default() - .show_diagnostics + .inline + .get_or_insert_default() + .enabled }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Show Close Button", - description: "Controls the appearance behavior of the tab's close button", + title: "Inline Update Debounce", + description: "The delay in milliseconds to show inline diagnostics after the last diagnostic update", field: Box::new(SettingField { pick: |settings_content| { - if let Some(tabs) = &settings_content.tabs { - &tabs.show_close_button + if let Some(diagnostics) = &settings_content.diagnostics { + if let Some(inline) = &diagnostics.inline { + &inline.update_debounce_ms + } else { + &None + } } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .tabs + .diagnostics .get_or_insert_default() - .show_close_button + .inline + .get_or_insert_default() + .update_debounce_ms }, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("Preview Tabs"), SettingsPageItem::SettingItem(SettingItem { - title: "Preview Tabs Enabled", - description: "Whether to show opened editors as preview tabs", + title: "Inline Padding", + description: "The amount of padding between the end of the source line and the start of the inline diagnostic", field: Box::new(SettingField { pick: |settings_content| { - if let Some(preview_tabs) = &settings_content.preview_tabs { - &preview_tabs.enabled + if let Some(diagnostics) = &settings_content.diagnostics { + if let Some(inline) = &diagnostics.inline { + &inline.padding + } else { + &None + } } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .preview_tabs + .diagnostics .get_or_insert_default() - .enabled + .inline + .get_or_insert_default() + .padding }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Enable Preview From File Finder", - description: "Whether to open tabs in preview mode when selected from the file finder", + title: "Inline Min Column", + description: "The minimum column to display inline diagnostics", field: Box::new(SettingField { pick: |settings_content| { - if let Some(preview_tabs) = &settings_content.preview_tabs { - &preview_tabs.enable_preview_from_file_finder + if let Some(diagnostics) = &settings_content.diagnostics { + if let Some(inline) = &diagnostics.inline { + &inline.min_column + } else { + &None + } } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .preview_tabs + .diagnostics .get_or_insert_default() - .enable_preview_from_file_finder + .inline + .get_or_insert_default() + .min_column }, }), metadata: None, + files: USER, }), + SettingsPageItem::SectionHeader("Performance"), SettingsPageItem::SettingItem(SettingItem { - title: "Enable Preview From Code Navigation", - description: "Whether a preview tab gets replaced when code navigation is used to navigate away from the tab", + title: "LSP Pull Diagnostics Enabled", + description: "Whether to pull for language server-powered diagnostics or not", field: Box::new(SettingField { pick: |settings_content| { - if let Some(preview_tabs) = &settings_content.preview_tabs { - &preview_tabs.enable_preview_from_code_navigation + if let Some(diagnostics) = &settings_content.diagnostics { + if let Some(lsp_pull) = &diagnostics.lsp_pull_diagnostics { + &lsp_pull.enabled + } else { + &None + } } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .preview_tabs + .diagnostics .get_or_insert_default() - .enable_preview_from_code_navigation + .lsp_pull_diagnostics + .get_or_insert_default() + .enabled }, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("Search Settings"), + // todo(settings_ui): Needs unit SettingsPageItem::SettingItem(SettingItem { - title: "Whole Word", - description: "Whether to search for whole words by default", + title: "LSP Pull Debounce", + description: "Minimum time to wait before pulling diagnostics from the language server(s)", field: Box::new(SettingField { pick: |settings_content| { - if let Some(search) = &settings_content.editor.search { - &search.whole_word + if let Some(diagnostics) = &settings_content.diagnostics { + if let Some(lsp_pull) = &diagnostics.lsp_pull_diagnostics { + &lsp_pull.debounce_ms + } else { + &None + } } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .search + .diagnostics .get_or_insert_default() - .whole_word + .lsp_pull_diagnostics + .get_or_insert_default() + .debounce_ms }, }), metadata: None, + files: USER, }), + ], + }, + SettingsPage { + title: "Debugger", + items: vec![ + SettingsPageItem::SectionHeader("General"), SettingsPageItem::SettingItem(SettingItem { - title: "Case Sensitive", - description: "Whether to search case-sensitively by default", + title: "Stepping Granularity", + description: "Determines the stepping granularity for debug operations", field: Box::new(SettingField { pick: |settings_content| { - if let Some(search) = &settings_content.editor.search { - &search.case_sensitive + if let Some(debugger) = &settings_content.debugger { + &debugger.stepping_granularity } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .search + .debugger .get_or_insert_default() - .case_sensitive + .stepping_granularity }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Include Ignored", - description: "Whether to include ignored files in search results by default", + title: "Save Breakpoints", + description: "Whether breakpoints should be reused across Zed sessions", field: Box::new(SettingField { pick: |settings_content| { - if let Some(search) = &settings_content.editor.search { - &search.include_ignored + if let Some(debugger) = &settings_content.debugger { + &debugger.save_breakpoints } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .editor - .search + .debugger .get_or_insert_default() - .include_ignored + .save_breakpoints }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Regex", - description: "Whether to use regex search by default", + title: "Timeout", + description: "Time in milliseconds until timeout error when connecting to a TCP debug adapter", field: Box::new(SettingField { pick: |settings_content| { - if let Some(search) = &settings_content.editor.search { - &search.regex + if let Some(debugger) = &settings_content.debugger { + &debugger.timeout } else { &None } }, pick_mut: |settings_content| { - &mut settings_content.editor.search.get_or_insert_default().regex + &mut settings_content.debugger.get_or_insert_default().timeout }, }), metadata: None, + files: USER, }), - SettingsPageItem::SectionHeader("File Finder"), SettingsPageItem::SettingItem(SettingItem { - title: "File Icons", - description: "Whether to show file icons in the file finder", + title: "Dock", + description: "The dock position of the debug panel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(file_finder) = &settings_content.file_finder { - &file_finder.file_icons + if let Some(debugger) = &settings_content.debugger { + &debugger.dock } else { &None } }, pick_mut: |settings_content| { - &mut settings_content - .file_finder - .get_or_insert_default() - .file_icons + &mut settings_content.debugger.get_or_insert_default().dock }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Modal Max Width", - description: "Determines how much space the file finder can take up in relation to the available window width", + title: "Log DAP Communications", + description: "Whether to log messages between active debug adapters and Zed", field: Box::new(SettingField { pick: |settings_content| { - if let Some(file_finder) = &settings_content.file_finder { - &file_finder.modal_max_width + if let Some(debugger) = &settings_content.debugger { + &debugger.log_dap_communications } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .file_finder + .debugger .get_or_insert_default() - .modal_max_width + .log_dap_communications }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Skip Focus For Active In Search", - description: "Whether the file finder should skip focus for the active file in search results", + title: "Format DAP Log Messages", + description: "Whether to format DAP messages when adding them to debug adapter logger", field: Box::new(SettingField { pick: |settings_content| { - if let Some(file_finder) = &settings_content.file_finder { - &file_finder.skip_focus_for_active_in_search + if let Some(debugger) = &settings_content.debugger { + &debugger.format_dap_log_messages } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .file_finder + .debugger .get_or_insert_default() - .skip_focus_for_active_in_search + .format_dap_log_messages }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Git Status", - description: "Whether to show the git status in the file finder", + title: "Button", + description: "Whether to show the debug button in the status bar", field: Box::new(SettingField { pick: |settings_content| { - if let Some(file_finder) = &settings_content.file_finder { - &file_finder.git_status + if let Some(debugger) = &settings_content.debugger { + &debugger.button } else { &None } }, pick_mut: |settings_content| { - &mut settings_content - .file_finder - .get_or_insert_default() - .git_status + &mut settings_content.debugger.get_or_insert_default().button }, }), metadata: None, + files: USER, }), - // todo: null by default - // 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, - // }), ], }, SettingsPage { - title: "Panels", + title: "Collaboration", items: vec![ - SettingsPageItem::SectionHeader("Project Panel"), - SettingsPageItem::SettingItem(SettingItem { - title: "Project Panel Button", - description: "Whether to show the project panel button in the status bar", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.button - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .project_panel - .get_or_insert_default() - .button - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Project Panel Dock", - description: "Where to dock the project panel", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.dock - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.project_panel.get_or_insert_default().dock - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Project Panel Default Width", - description: "Default width of the project panel in pixels", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.default_width - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .project_panel - .get_or_insert_default() - .default_width - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Hide .gitignore", - description: "Whether to hide the gitignore entries in the project panel", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.hide_gitignore - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .project_panel - .get_or_insert_default() - .hide_gitignore - }, - }), - metadata: None, - }), + SettingsPageItem::SectionHeader("Calls"), SettingsPageItem::SettingItem(SettingItem { - title: "Entry Spacing", - description: "Spacing between worktree entries in the project panel", + title: "Mute On Join", + description: "Whether the microphone should be muted when joining a channel or a call", field: Box::new(SettingField { pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.entry_spacing + if let Some(calls) = &settings_content.calls { + &calls.mute_on_join } else { &None } }, pick_mut: |settings_content| { - &mut settings_content - .project_panel - .get_or_insert_default() - .entry_spacing + &mut settings_content.calls.get_or_insert_default().mute_on_join }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "File Icons", - description: "Whether to show folder icons or chevrons for directories in the project panel", + title: "Share On Join", + description: "Whether your current project should be shared when joining an empty channel", field: Box::new(SettingField { pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.file_icons + if let Some(calls) = &settings_content.calls { + &calls.share_on_join } else { &None } }, pick_mut: |settings_content| { - &mut settings_content - .project_panel - .get_or_insert_default() - .file_icons + &mut settings_content.calls.get_or_insert_default().share_on_join }, }), metadata: None, + files: USER, }), + SettingsPageItem::SectionHeader("Experimental"), SettingsPageItem::SettingItem(SettingItem { - title: "Folder Icons", - description: "Whether to show folder icons or chevrons for directories in the project panel", + title: "Rodio Audio", + description: "Opt into the new audio system", field: Box::new(SettingField { pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.folder_icons + if let Some(audio) = &settings_content.audio { + &audio.rodio_audio } else { &None } }, pick_mut: |settings_content| { - &mut settings_content - .project_panel - .get_or_insert_default() - .folder_icons + &mut settings_content.audio.get_or_insert_default().rodio_audio }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Git Status", - description: "Whether to show the git status in the project panel", + title: "Auto Microphone Volume", + description: "Automatically adjust microphone volume (requires Rodio Audio)", field: Box::new(SettingField { pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.git_status + if let Some(audio) = &settings_content.audio { + &audio.auto_microphone_volume } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .project_panel + .audio .get_or_insert_default() - .git_status + .auto_microphone_volume }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Indent Size", - description: "Amount of indentation for nested items", + title: "Auto Speaker Volume", + description: "Automatically adjust volume of other call members (requires Rodio Audio)", field: Box::new(SettingField { pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.indent_size + if let Some(audio) = &settings_content.audio { + &audio.auto_speaker_volume } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .project_panel + .audio .get_or_insert_default() - .indent_size + .auto_speaker_volume }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Auto Reveal Entries", - description: "Whether to reveal it in the project panel automatically when a corresponding project entry becomes active", + title: "Denoise", + description: "Remove background noises (requires Rodio Audio)", field: Box::new(SettingField { pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.auto_reveal_entries + if let Some(audio) = &settings_content.audio { + &audio.denoise } else { &None } }, pick_mut: |settings_content| { - &mut settings_content - .project_panel - .get_or_insert_default() - .auto_reveal_entries + &mut settings_content.audio.get_or_insert_default().denoise }, }), metadata: None, + files: USER, }), SettingsPageItem::SettingItem(SettingItem { - title: "Starts Open", - description: "Whether the project panel should open on startup", + title: "Legacy Audio Compatible", + description: "Use audio parameters compatible with previous versions (requires Rodio Audio)", field: Box::new(SettingField { pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.starts_open + if let Some(audio) = &settings_content.audio { + &audio.legacy_audio_compatible } else { &None } }, pick_mut: |settings_content| { &mut settings_content - .project_panel + .audio .get_or_insert_default() - .starts_open + .legacy_audio_compatible }, }), metadata: None, + files: USER, }), + ], + }, + SettingsPage { + title: "AI", + items: vec![ + SettingsPageItem::SectionHeader("General"), SettingsPageItem::SettingItem(SettingItem { - title: "Auto Fold Directories", - description: "Whether to fold directories automatically and show compact folders when a directory has only one subdirectory inside", + title: "Disable AI", + description: "Whether to disable all AI features in Zed", field: Box::new(SettingField { - pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.auto_fold_dirs - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .project_panel - .get_or_insert_default() - .auto_fold_dirs - }, - }), - 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 { - // 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: "Show Diagnostics", - description: "Which files containing diagnostic errors/warnings to mark in the project panel", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.show_diagnostics - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .project_panel - .get_or_insert_default() - .show_diagnostics - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Sticky Scroll", - description: "Whether to stick parent directories at top of the project panel", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.sticky_scroll - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .project_panel - .get_or_insert_default() - .sticky_scroll - }, - }), - metadata: None, - }), - // 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 { - title: "Drag and Drop", - description: "Whether to enable drag-and-drop operations in the project panel", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.drag_and_drop - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .project_panel - .get_or_insert_default() - .drag_and_drop - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Hide Root", - description: "Whether to hide the root entry when only one folder is open in the window", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(project_panel) = &settings_content.project_panel { - &project_panel.hide_root - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .project_panel - .get_or_insert_default() - .hide_root - }, - }), - metadata: None, - }), - SettingsPageItem::SectionHeader("Terminal Panel"), - SettingsPageItem::SettingItem(SettingItem { - title: "Terminal Dock", - description: "Where to dock the terminal panel", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(terminal) = &settings_content.terminal { - &terminal.dock - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.terminal.get_or_insert_default().dock - }, - }), - metadata: None, - }), - SettingsPageItem::SectionHeader("Outline Panel"), - SettingsPageItem::SettingItem(SettingItem { - title: "Outline Panel Button", - description: "Whether to show the outline panel button in the status bar", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(outline_panel) = &settings_content.outline_panel { - &outline_panel.button - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .outline_panel - .get_or_insert_default() - .button - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Outline Panel Dock", - description: "Where to dock the outline panel", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(outline_panel) = &settings_content.outline_panel { - &outline_panel.dock - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.outline_panel.get_or_insert_default().dock - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Outline Panel Default Width", - description: "Default width of the outline panel in pixels", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(outline_panel) = &settings_content.outline_panel { - &outline_panel.default_width - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .outline_panel - .get_or_insert_default() - .default_width - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "File Icons", - description: "Whether to show file icons in the outline panel", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(outline_panel) = &settings_content.outline_panel { - &outline_panel.file_icons - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .outline_panel - .get_or_insert_default() - .file_icons - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Folder Icons", - description: "Whether to show folder icons or chevrons for directories in the outline panel", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(outline_panel) = &settings_content.outline_panel { - &outline_panel.folder_icons - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .outline_panel - .get_or_insert_default() - .folder_icons - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Git Status", - description: "Whether to show the git status in the outline panel", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(outline_panel) = &settings_content.outline_panel { - &outline_panel.git_status - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .outline_panel - .get_or_insert_default() - .git_status - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Indent Size", - description: "Amount of indentation for nested items", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(outline_panel) = &settings_content.outline_panel { - &outline_panel.indent_size - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .outline_panel - .get_or_insert_default() - .indent_size - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Auto Reveal Entries", - description: "Whether to reveal when a corresponding outline entry becomes active", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(outline_panel) = &settings_content.outline_panel { - &outline_panel.auto_reveal_entries - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .outline_panel - .get_or_insert_default() - .auto_reveal_entries - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Auto Fold Directories", - description: "Whether to fold directories automatically when a directory has only one directory inside", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(outline_panel) = &settings_content.outline_panel { - &outline_panel.auto_fold_dirs - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .outline_panel - .get_or_insert_default() - .auto_fold_dirs - }, - }), - metadata: None, - }), - // 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::SectionHeader("Git Panel"), - SettingsPageItem::SettingItem(SettingItem { - title: "Button", - description: "Whether to show the git panel button in the status bar", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(git_panel) = &settings_content.git_panel { - &git_panel.button - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.git_panel.get_or_insert_default().button - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Dock", - description: "Where to dock the git panel", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(git_panel) = &settings_content.git_panel { - &git_panel.dock - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.git_panel.get_or_insert_default().dock - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Default Width", - description: "Default width of the git panel in pixels", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(git_panel) = &settings_content.git_panel { - &git_panel.default_width - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .git_panel - .get_or_insert_default() - .default_width - }, - }), - metadata: None, - }), - SettingsPageItem::SectionHeader("Notification Panel"), - SettingsPageItem::SettingItem(SettingItem { - title: "Notification Panel Button", - description: "Whether to show the notification panel button in the status bar", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(notification_panel) = &settings_content.notification_panel { - ¬ification_panel.button - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .notification_panel - .get_or_insert_default() - .button - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Notification Panel Dock", - description: "Where to dock the notification panel", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(notification_panel) = &settings_content.notification_panel { - ¬ification_panel.dock - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .notification_panel - .get_or_insert_default() - .dock - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Notification Panel Default Width", - description: "Default width of the notification panel in pixels", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(notification_panel) = &settings_content.notification_panel { - ¬ification_panel.default_width - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .notification_panel - .get_or_insert_default() - .default_width - }, - }), - metadata: None, - }), - SettingsPageItem::SectionHeader("Collaboration Panel"), - SettingsPageItem::SettingItem(SettingItem { - title: "Collaboration Panel Button", - description: "Whether to show the collaboration panel button in the status bar", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(collaboration_panel) = &settings_content.collaboration_panel - { - &collaboration_panel.button - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .collaboration_panel - .get_or_insert_default() - .button - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Collaboration Panel Dock", - description: "Where to dock the collaboration panel", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(collaboration_panel) = &settings_content.collaboration_panel - { - &collaboration_panel.dock - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .collaboration_panel - .get_or_insert_default() - .dock - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Collaboration Panel Default Width", - description: "Default width of the collaboration panel in pixels", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(collaboration_panel) = &settings_content.collaboration_panel - { - &collaboration_panel.default_width - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .collaboration_panel - .get_or_insert_default() - .default_width - }, - }), - metadata: None, - }), - ], - }, - SettingsPage { - title: "Version Control", - items: vec![ - SettingsPageItem::SectionHeader("Git"), - SettingsPageItem::SettingItem(SettingItem { - title: "Git Gutter", - description: "Control whether git status is shown in the editor's gutter", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(git) = &settings_content.git { - &git.git_gutter - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.git.get_or_insert_default().git_gutter - }, - }), - metadata: None, - }), - // todo(settings_ui): Figure out the right default for this value in default.json - SettingsPageItem::SettingItem(SettingItem { - title: "Gutter Debounce", - description: "Debounce threshold in milliseconds after which changes are reflected in the git gutter", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(git) = &settings_content.git { - &git.gutter_debounce - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.git.get_or_insert_default().gutter_debounce - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Inline Git Blame", - description: "Whether or not to show git blame data inline in the currently focused line", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(git) = &settings_content.git { - if let Some(inline_blame) = &git.inline_blame { - &inline_blame.enabled - } else { - &None - } - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .git - .get_or_insert_default() - .inline_blame - .get_or_insert_default() - .enabled - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Inline Git Blame Delay", - description: "The delay after which the inline blame information is shown", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(git) = &settings_content.git { - if let Some(inline_blame) = &git.inline_blame { - &inline_blame.delay_ms - } else { - &None - } - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .git - .get_or_insert_default() - .inline_blame - .get_or_insert_default() - .delay_ms - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Inline Git Blame Padding", - description: "Padding between the end of the source line and the start of the inline blame in columns", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(git) = &settings_content.git { - if let Some(inline_blame) = &git.inline_blame { - &inline_blame.padding - } else { - &None - } - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .git - .get_or_insert_default() - .inline_blame - .get_or_insert_default() - .padding - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Inline Git Blame Min Column", - description: "The minimum column number to show the inline blame information at", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(git) = &settings_content.git { - if let Some(inline_blame) = &git.inline_blame { - &inline_blame.min_column - } else { - &None - } - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .git - .get_or_insert_default() - .inline_blame - .get_or_insert_default() - .min_column - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Show Commit Summary", - description: "Whether to show commit summary as part of the inline blame", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(git) = &settings_content.git { - if let Some(inline_blame) = &git.inline_blame { - &inline_blame.show_commit_summary - } else { - &None - } - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .git - .get_or_insert_default() - .inline_blame - .get_or_insert_default() - .show_commit_summary - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Show Avatar", - description: "Whether to show the avatar of the author of the commit", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(git) = &settings_content.git { - if let Some(blame) = &git.blame { - &blame.show_avatar - } else { - &None - } - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .git - .get_or_insert_default() - .blame - .get_or_insert_default() - .show_avatar - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Show Author Name In Branch Picker", - description: "Whether to show author name as part of the commit information in branch picker", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(git) = &settings_content.git { - if let Some(branch_picker) = &git.branch_picker { - &branch_picker.show_author_name - } else { - &None - } - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .git - .get_or_insert_default() - .branch_picker - .get_or_insert_default() - .show_author_name - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Hunk Style", - description: "How git hunks are displayed visually in the editor", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(git) = &settings_content.git { - &git.hunk_style - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.git.get_or_insert_default().hunk_style - }, - }), - metadata: None, - }), - ], - }, - SettingsPage { - title: "System & Network", - items: vec![ - SettingsPageItem::SectionHeader("Network"), - // todo(settings_ui): Proxy needs a default - // 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: "Server URL", - description: "The URL of the Zed server to connect to", - field: Box::new(SettingField { - pick: |settings_content| &settings_content.server_url, - pick_mut: |settings_content| &mut settings_content.server_url, - }), - metadata: Some(Box::new(SettingsFieldMetadata { - placeholder: Some("https://zed.dev"), - })), - }), - SettingsPageItem::SectionHeader("System"), - SettingsPageItem::SettingItem(SettingItem { - title: "Auto Update", - description: "Whether or not to automatically check for updates", - field: Box::new(SettingField { - pick: |settings_content| &settings_content.auto_update, - pick_mut: |settings_content| &mut settings_content.auto_update, - }), - metadata: None, - }), - ], - }, - SettingsPage { - title: "Diagnostics & Errors", - items: vec![ - SettingsPageItem::SectionHeader("Filtering"), - SettingsPageItem::SettingItem(SettingItem { - title: "Max Severity", - description: "Which level to use to filter out diagnostics displayed in the editor", - field: Box::new(SettingField { - pick: |settings_content| &settings_content.editor.diagnostics_max_severity, - pick_mut: |settings_content| { - &mut settings_content.editor.diagnostics_max_severity - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Include Warnings", - description: "Whether to show warnings or not by default", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(diagnostics) = &settings_content.diagnostics { - &diagnostics.include_warnings - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .diagnostics - .get_or_insert_default() - .include_warnings - }, - }), - metadata: None, - }), - SettingsPageItem::SectionHeader("Inline"), - SettingsPageItem::SettingItem(SettingItem { - title: "Inline Diagnostics Enabled", - description: "Whether to show diagnostics inline or not", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(diagnostics) = &settings_content.diagnostics { - if let Some(inline) = &diagnostics.inline { - &inline.enabled - } else { - &None - } - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .diagnostics - .get_or_insert_default() - .inline - .get_or_insert_default() - .enabled - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Inline Update Debounce", - description: "The delay in milliseconds to show inline diagnostics after the last diagnostic update", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(diagnostics) = &settings_content.diagnostics { - if let Some(inline) = &diagnostics.inline { - &inline.update_debounce_ms - } else { - &None - } - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .diagnostics - .get_or_insert_default() - .inline - .get_or_insert_default() - .update_debounce_ms - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Inline Padding", - description: "The amount of padding between the end of the source line and the start of the inline diagnostic", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(diagnostics) = &settings_content.diagnostics { - if let Some(inline) = &diagnostics.inline { - &inline.padding - } else { - &None - } - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .diagnostics - .get_or_insert_default() - .inline - .get_or_insert_default() - .padding - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Inline Min Column", - description: "The minimum column to display inline diagnostics", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(diagnostics) = &settings_content.diagnostics { - if let Some(inline) = &diagnostics.inline { - &inline.min_column - } else { - &None - } - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .diagnostics - .get_or_insert_default() - .inline - .get_or_insert_default() - .min_column - }, - }), - metadata: None, - }), - SettingsPageItem::SectionHeader("Performance"), - SettingsPageItem::SettingItem(SettingItem { - title: "LSP Pull Diagnostics Enabled", - description: "Whether to pull for language server-powered diagnostics or not", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(diagnostics) = &settings_content.diagnostics { - if let Some(lsp_pull) = &diagnostics.lsp_pull_diagnostics { - &lsp_pull.enabled - } else { - &None - } - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .diagnostics - .get_or_insert_default() - .lsp_pull_diagnostics - .get_or_insert_default() - .enabled - }, - }), - metadata: None, - }), - // todo(settings_ui): Needs unit - SettingsPageItem::SettingItem(SettingItem { - title: "LSP Pull Debounce", - description: "Minimum time to wait before pulling diagnostics from the language server(s)", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(diagnostics) = &settings_content.diagnostics { - if let Some(lsp_pull) = &diagnostics.lsp_pull_diagnostics { - &lsp_pull.debounce_ms - } else { - &None - } - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .diagnostics - .get_or_insert_default() - .lsp_pull_diagnostics - .get_or_insert_default() - .debounce_ms - }, - }), - metadata: None, - }), - ], - }, - SettingsPage { - title: "Debugger", - items: vec![ - SettingsPageItem::SectionHeader("General"), - SettingsPageItem::SettingItem(SettingItem { - title: "Stepping Granularity", - description: "Determines the stepping granularity for debug operations", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(debugger) = &settings_content.debugger { - &debugger.stepping_granularity - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .debugger - .get_or_insert_default() - .stepping_granularity - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Save Breakpoints", - description: "Whether breakpoints should be reused across Zed sessions", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(debugger) = &settings_content.debugger { - &debugger.save_breakpoints - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .debugger - .get_or_insert_default() - .save_breakpoints - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Timeout", - description: "Time in milliseconds until timeout error when connecting to a TCP debug adapter", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(debugger) = &settings_content.debugger { - &debugger.timeout - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.debugger.get_or_insert_default().timeout - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Dock", - description: "The dock position of the debug panel", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(debugger) = &settings_content.debugger { - &debugger.dock - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.debugger.get_or_insert_default().dock - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Log DAP Communications", - description: "Whether to log messages between active debug adapters and Zed", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(debugger) = &settings_content.debugger { - &debugger.log_dap_communications - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .debugger - .get_or_insert_default() - .log_dap_communications - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Format DAP Log Messages", - description: "Whether to format DAP messages when adding them to debug adapter logger", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(debugger) = &settings_content.debugger { - &debugger.format_dap_log_messages - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .debugger - .get_or_insert_default() - .format_dap_log_messages - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Button", - description: "Whether to show the debug button in the status bar", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(debugger) = &settings_content.debugger { - &debugger.button - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.debugger.get_or_insert_default().button - }, - }), - metadata: None, - }), - ], - }, - SettingsPage { - title: "Collaboration", - items: vec![ - SettingsPageItem::SectionHeader("Calls"), - SettingsPageItem::SettingItem(SettingItem { - title: "Mute On Join", - description: "Whether the microphone should be muted when joining a channel or a call", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(calls) = &settings_content.calls { - &calls.mute_on_join - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.calls.get_or_insert_default().mute_on_join - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Share On Join", - description: "Whether your current project should be shared when joining an empty channel", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(calls) = &settings_content.calls { - &calls.share_on_join - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.calls.get_or_insert_default().share_on_join - }, - }), - metadata: None, - }), - SettingsPageItem::SectionHeader("Experimental"), - SettingsPageItem::SettingItem(SettingItem { - title: "Rodio Audio", - description: "Opt into the new audio system", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(audio) = &settings_content.audio { - &audio.rodio_audio - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.audio.get_or_insert_default().rodio_audio - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Auto Microphone Volume", - description: "Automatically adjust microphone volume (requires Rodio Audio)", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(audio) = &settings_content.audio { - &audio.auto_microphone_volume - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .audio - .get_or_insert_default() - .auto_microphone_volume - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Auto Speaker Volume", - description: "Automatically adjust volume of other call members (requires Rodio Audio)", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(audio) = &settings_content.audio { - &audio.auto_speaker_volume - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .audio - .get_or_insert_default() - .auto_speaker_volume - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Denoise", - description: "Remove background noises (requires Rodio Audio)", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(audio) = &settings_content.audio { - &audio.denoise - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content.audio.get_or_insert_default().denoise - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Legacy Audio Compatible", - description: "Use audio parameters compatible with previous versions (requires Rodio Audio)", - field: Box::new(SettingField { - pick: |settings_content| { - if let Some(audio) = &settings_content.audio { - &audio.legacy_audio_compatible - } else { - &None - } - }, - pick_mut: |settings_content| { - &mut settings_content - .audio - .get_or_insert_default() - .legacy_audio_compatible - }, - }), - metadata: None, - }), - ], - }, - SettingsPage { - title: "AI", - items: vec![ - SettingsPageItem::SectionHeader("General"), - SettingsPageItem::SettingItem(SettingItem { - title: "Disable AI", - description: "Whether to disable all AI features in Zed", - field: Box::new(SettingField { - pick: |settings_content| &settings_content.disable_ai, - pick_mut: |settings_content| &mut settings_content.disable_ai, - }), - metadata: None, - }), - ], - }, - ] -} - -pub(crate) fn project_settings_data() -> Vec { - vec![ - SettingsPage { - title: "Project", - items: vec![ - SettingsPageItem::SectionHeader("Worktree Settings Content"), - SettingsPageItem::SettingItem(SettingItem { - title: "Project Name", - description: "The displayed name of this project. If not set, the root directory name", - field: Box::new(SettingField { - pick: |settings_content| &settings_content.project.worktree.project_name, - pick_mut: |settings_content| { - &mut settings_content.project.worktree.project_name - }, - }), - metadata: Some(Box::new(SettingsFieldMetadata { - placeholder: Some("A new name"), - })), - }), - ], - }, - SettingsPage { - title: "Appearance & Behavior", - items: vec![ - SettingsPageItem::SectionHeader("Guides"), - SettingsPageItem::SettingItem(SettingItem { - title: "Show Wrap Guides", - description: "Whether to show wrap guides (vertical rulers)", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .show_wrap_guides - }, - pick_mut: |settings_content| { - &mut settings_content - .project - .all_languages - .defaults - .show_wrap_guides - }, - }), - metadata: None, - }), - // todo(settings_ui): This needs a custom component - // SettingsPageItem::SettingItem(SettingItem { - // title: "Wrap Guides", - // description: "Character counts at which to show wrap guides", - // field: Box::new(SettingField { - // pick: |settings_content| { - // &settings_content - // .project - // .all_languages - // .defaults - // .wrap_guides - // }, - // pick_mut: |settings_content| { - // &mut settings_content - // .project - // .all_languages - // .defaults - // .wrap_guides - // }, - // }), - // metadata: None, - // }), - SettingsPageItem::SectionHeader("Whitespace"), - SettingsPageItem::SettingItem(SettingItem { - title: "Show Whitespace", - description: "Whether to show tabs and spaces", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .show_whitespaces - }, - pick_mut: |settings_content| { - &mut settings_content - .project - .all_languages - .defaults - .show_whitespaces - }, - }), - metadata: None, - }), - ], - }, - SettingsPage { - title: "Editing", - items: vec![ - SettingsPageItem::SectionHeader("Indentation"), - // todo(settings_ui): Needs Number Field - // SettingsPageItem::SettingItem(SettingItem { - // title: "Tab Size", - // description: "How many columns a tab should occupy", - // field: Box::new(SettingField { - // pick: |settings_content| &settings_content.project.all_languages.defaults.tab_size, - // pick_mut: |settings_content| &mut settings_content.project.all_languages.defaults.tab_size, - // }), - // metadata: None, - // }), - SettingsPageItem::SettingItem(SettingItem { - title: "Hard Tabs", - description: "Whether to indent lines using tab characters, as opposed to multiple spaces", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content.project.all_languages.defaults.hard_tabs - }, - pick_mut: |settings_content| { - &mut settings_content.project.all_languages.defaults.hard_tabs - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Auto Indent", - description: "Whether indentation should be adjusted based on the context whilst typing", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content.project.all_languages.defaults.auto_indent - }, - pick_mut: |settings_content| { - &mut settings_content.project.all_languages.defaults.auto_indent - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Auto Indent On Paste", - description: "Whether indentation of pasted content should be adjusted based on the context", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .auto_indent_on_paste - }, - pick_mut: |settings_content| { - &mut settings_content - .project - .all_languages - .defaults - .auto_indent_on_paste - }, - }), - metadata: None, - }), - SettingsPageItem::SectionHeader("Wrapping"), - // todo(settings_ui): Needs Number Field - // SettingsPageItem::SettingItem(SettingItem { - // title: "Preferred Line Length", - // description: "The column at which to soft-wrap lines, for buffers where soft-wrap is enabled", - // field: Box::new(SettingField { - // pick: |settings_content| &settings_content.project.all_languages.defaults.preferred_line_length, - // pick_mut: |settings_content| &mut settings_content.project.all_languages.defaults.preferred_line_length, - // }), - // metadata: None, - // }), - SettingsPageItem::SettingItem(SettingItem { - title: "Soft Wrap", - description: "How to soft-wrap long lines of text", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content.project.all_languages.defaults.soft_wrap - }, - pick_mut: |settings_content| { - &mut settings_content.project.all_languages.defaults.soft_wrap - }, - }), - metadata: None, - }), - SettingsPageItem::SectionHeader("Auto Actions"), - SettingsPageItem::SettingItem(SettingItem { - title: "Use Autoclose", - description: "Whether to automatically type closing characters for you", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .use_autoclose - }, - pick_mut: |settings_content| { - &mut settings_content - .project - .all_languages - .defaults - .use_autoclose - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Use Auto Surround", - description: "Whether to automatically surround text with characters for you", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .use_auto_surround - }, - pick_mut: |settings_content| { - &mut settings_content - .project - .all_languages - .defaults - .use_auto_surround - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Use On Type Format", - description: "Whether to use additional LSP queries to format the code after every trigger symbol input", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .use_on_type_format - }, - pick_mut: |settings_content| { - &mut settings_content - .project - .all_languages - .defaults - .use_on_type_format - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Always Treat Brackets As Autoclosed", - description: "Controls how the editor handles the autoclosed characters", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .always_treat_brackets_as_autoclosed - }, - pick_mut: |settings_content| { - &mut settings_content - .project - .all_languages - .defaults - .always_treat_brackets_as_autoclosed - }, - }), - metadata: None, - }), - SettingsPageItem::SectionHeader("Formatting"), - SettingsPageItem::SettingItem(SettingItem { - title: "Remove Trailing Whitespace On Save", - description: "Whether or not to remove any trailing whitespace from lines of a buffer before saving it", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .remove_trailing_whitespace_on_save - }, - pick_mut: |settings_content| { - &mut settings_content - .project - .all_languages - .defaults - .remove_trailing_whitespace_on_save - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Ensure Final Newline On Save", - description: "Whether or not to ensure there's a single newline at the end of a buffer when saving it", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .ensure_final_newline_on_save - }, - pick_mut: |settings_content| { - &mut settings_content - .project - .all_languages - .defaults - .ensure_final_newline_on_save - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Extend Comment On Newline", - description: "Whether to start a new line with a comment when a previous line is a comment as well", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .extend_comment_on_newline - }, - pick_mut: |settings_content| { - &mut settings_content - .project - .all_languages - .defaults - .extend_comment_on_newline - }, - }), - metadata: None, - }), - SettingsPageItem::SectionHeader("Completions"), - SettingsPageItem::SettingItem(SettingItem { - title: "Show Completions On Input", - description: "Whether to pop the completions menu while typing in an editor without explicitly requesting it", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .show_completions_on_input - }, - pick_mut: |settings_content| { - &mut settings_content - .project - .all_languages - .defaults - .show_completions_on_input - }, - }), - metadata: None, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Show Completion Documentation", - description: "Whether to display inline and alongside documentation for items in the completions menu", - field: Box::new(SettingField { - pick: |settings_content| { - &settings_content - .project - .all_languages - .defaults - .show_completion_documentation - }, - pick_mut: |settings_content| { - &mut settings_content - .project - .all_languages - .defaults - .show_completion_documentation - }, + pick: |settings_content| &settings_content.disable_ai, + pick_mut: |settings_content| &mut settings_content.disable_ai, }), metadata: None, + files: USER, }), ], }, @@ -4357,6 +3902,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Hard Tabs", @@ -4372,6 +3918,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Auto Indent", @@ -4387,6 +3934,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Auto Indent On Paste", @@ -4404,6 +3952,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SectionHeader("Wrapping"), SettingsPageItem::SettingItem(SettingItem { @@ -4420,6 +3969,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Show Wrap Guides", @@ -4435,6 +3985,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Preferred Line Length", @@ -4452,6 +4003,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Wrap Guides", @@ -4470,6 +4022,7 @@ fn language_settings_data() -> Vec { .unimplemented(), ), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Allow Rewrap", @@ -4485,6 +4038,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SectionHeader("Indent Guides"), SettingsPageItem::SettingItem(SettingItem { @@ -4507,6 +4061,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Line Width", @@ -4528,6 +4083,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Active Line Width", @@ -4552,6 +4108,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Coloring", @@ -4573,6 +4130,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Background Coloring", @@ -4597,6 +4155,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SectionHeader("Formatting"), SettingsPageItem::SettingItem(SettingItem { @@ -4618,6 +4177,7 @@ fn language_settings_data() -> Vec { }, ), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Remove Trailing Whitespace On Save", @@ -4635,6 +4195,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Ensure Final Newline On Save", @@ -4652,6 +4213,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Formatter", @@ -4670,6 +4232,7 @@ fn language_settings_data() -> Vec { .unimplemented(), ), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Use On Type Format", @@ -4687,6 +4250,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Code Actions On Format", @@ -4707,6 +4271,7 @@ fn language_settings_data() -> Vec { .unimplemented(), ), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SectionHeader("Prettier"), SettingsPageItem::SettingItem(SettingItem { @@ -4729,6 +4294,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Parser", @@ -4750,6 +4316,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Plugins", @@ -4774,6 +4341,7 @@ fn language_settings_data() -> Vec { .unimplemented(), ), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Options", @@ -4798,6 +4366,7 @@ fn language_settings_data() -> Vec { .unimplemented(), ), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SectionHeader("Autoclose"), SettingsPageItem::SettingItem(SettingItem { @@ -4814,6 +4383,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Use Auto Surround", @@ -4831,6 +4401,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Always Treat Brackets As Autoclosed", @@ -4848,6 +4419,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Jsx Tag Auto Close", @@ -4869,6 +4441,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SectionHeader("LSP"), SettingsPageItem::SettingItem(SettingItem { @@ -4887,6 +4460,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Language Servers", @@ -4907,6 +4481,7 @@ fn language_settings_data() -> Vec { .unimplemented(), ), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Linked Edits", @@ -4922,6 +4497,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SectionHeader("Edit Predictions"), SettingsPageItem::SettingItem(SettingItem { @@ -4940,6 +4516,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Edit Predictions Disabled In", @@ -4960,6 +4537,7 @@ fn language_settings_data() -> Vec { .unimplemented(), ), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SectionHeader("Whitespace"), SettingsPageItem::SettingItem(SettingItem { @@ -4976,6 +4554,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Space Whitespace Indicator", @@ -5000,6 +4579,7 @@ fn language_settings_data() -> Vec { .unimplemented(), ), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Tab Whitespace Indicator", @@ -5024,6 +4604,7 @@ fn language_settings_data() -> Vec { .unimplemented(), ), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SectionHeader("Completions"), SettingsPageItem::SettingItem(SettingItem { @@ -5042,6 +4623,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Show Completion Documentation", @@ -5059,6 +4641,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Words", @@ -5080,6 +4663,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Words Min Length", @@ -5104,6 +4688,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Lsp", @@ -5125,6 +4710,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Lsp Fetch Timeout Ms", @@ -5149,6 +4735,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Lsp Insert Mode", @@ -5170,6 +4757,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SectionHeader("Inlay Hints"), SettingsPageItem::SettingItem(SettingItem { @@ -5192,6 +4780,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Show Value Hints", @@ -5216,6 +4805,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Show Type Hints", @@ -5237,6 +4827,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Show Parameter Hints", @@ -5261,6 +4852,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Show Other Hints", @@ -5285,6 +4877,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Show Background", @@ -5306,6 +4899,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Edit Debounce Ms", @@ -5330,6 +4924,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Scroll Debounce Ms", @@ -5354,10 +4949,11 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Toggle On Modifiers Press", - description: "Toggles inlay hints (hides or shows) when the user presses the modifiers specified", + description: "Toggles inlay hints (hides or shows) when the user | LOCAL presses the modifiers specified", field: Box::new( SettingField { pick: |settings_content| { @@ -5381,6 +4977,7 @@ fn language_settings_data() -> Vec { .unimplemented(), ), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SectionHeader("Tasks"), SettingsPageItem::SettingItem(SettingItem { @@ -5403,6 +5000,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Variables", @@ -5427,6 +5025,7 @@ fn language_settings_data() -> Vec { .unimplemented(), ), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Prefer Lsp", @@ -5448,6 +5047,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SectionHeader("Miscellaneous"), SettingsPageItem::SettingItem(SettingItem { @@ -5467,6 +5067,7 @@ fn language_settings_data() -> Vec { .unimplemented(), ), metadata: None, + files: USER | LOCAL, }), SettingsPageItem::SettingItem(SettingItem { title: "Extend Comment On Newline", @@ -5484,6 +5085,7 @@ fn language_settings_data() -> Vec { }, }), metadata: None, + files: USER | LOCAL, }), ] } diff --git a/crates/settings_ui/src/settings_ui.rs b/crates/settings_ui/src/settings_ui.rs index faf439eb061f6016c0482199218236bb177d946b..e9b50b716171d0e479df01b697c8189373de154f 100644 --- a/crates/settings_ui/src/settings_ui.rs +++ b/crates/settings_ui/src/settings_ui.rs @@ -673,6 +673,55 @@ struct SettingItem { description: &'static str, field: Box, metadata: Option>, + files: FileMask, +} + +#[derive(PartialEq, Eq, Clone, Copy)] +struct FileMask(u8); + +impl std::fmt::Debug for FileMask { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "FileMask(")?; + let mut items = vec![]; + + if self.contains(USER) { + items.push("USER"); + } + if self.contains(LOCAL) { + items.push("LOCAL"); + } + if self.contains(SERVER) { + items.push("SERVER"); + } + + write!(f, "{})", items.join(" | ")) + } +} + +const USER: FileMask = FileMask(1 << 0); +const LOCAL: FileMask = FileMask(1 << 2); +const SERVER: FileMask = FileMask(1 << 3); + +impl std::ops::BitAnd for FileMask { + type Output = Self; + + fn bitand(self, other: Self) -> Self { + Self(self.0 & other.0) + } +} + +impl std::ops::BitOr for FileMask { + type Output = Self; + + fn bitor(self, other: Self) -> Self { + Self(self.0 | other.0) + } +} + +impl FileMask { + fn contains(&self, other: FileMask) -> bool { + self.0 & other.0 != 0 + } } impl PartialEq for SettingItem { @@ -690,6 +739,7 @@ impl PartialEq for SettingItem { #[derive(Clone)] struct SubPageLink { title: &'static str, + files: FileMask, render: Arc< dyn Fn(&mut SettingsWindow, &mut Window, &mut Context) -> AnyElement + 'static @@ -713,14 +763,6 @@ enum SettingsUiFile { } impl SettingsUiFile { - fn pages(&self) -> Vec { - match self { - SettingsUiFile::User => page_data::user_settings_data(), - SettingsUiFile::Local(_) => page_data::project_settings_data(), - SettingsUiFile::Server(_) => page_data::user_settings_data(), - } - } - fn name(&self) -> SharedString { match self { SettingsUiFile::User => SharedString::new_static("User"), @@ -748,6 +790,14 @@ impl SettingsUiFile { SettingsUiFile::Server(_) => settings::SettingsFile::Server, } } + + fn mask(&self) -> FileMask { + match self { + SettingsUiFile::User => USER, + SettingsUiFile::Local(_) => LOCAL, + SettingsUiFile::Server(_) => SERVER, + } + } } impl SettingsWindow { @@ -939,6 +989,45 @@ impl SettingsWindow { }) } + fn filter_matches_to_file(&mut self) { + let current_file = self.current_file.mask(); + for (page, page_filter) in std::iter::zip(&self.pages, &mut self.search_matches) { + let mut header_index = 0; + let mut any_found_since_last_header = true; + + for (index, item) in page.items.iter().enumerate() { + match item { + SettingsPageItem::SectionHeader(_) => { + if !any_found_since_last_header { + page_filter[header_index] = false; + } + header_index = index; + any_found_since_last_header = false; + } + SettingsPageItem::SettingItem(setting_item) => { + if !setting_item.files.contains(current_file) { + page_filter[index] = false; + } else { + any_found_since_last_header = true; + } + } + SettingsPageItem::SubPageLink(sub_page_link) => { + if !sub_page_link.files.contains(current_file) { + page_filter[index] = false; + } else { + any_found_since_last_header = true; + } + } + } + } + if let Some(last_header) = page_filter.get_mut(header_index) + && !any_found_since_last_header + { + *last_header = false; + } + } + } + fn update_matches(&mut self, cx: &mut Context) { self.search_task.take(); let query = self.search_bar.read(cx).text(cx); @@ -946,6 +1035,7 @@ impl SettingsWindow { for page in &mut self.search_matches { page.fill(true); } + self.filter_matches_to_file(); cx.notify(); return; } @@ -1011,6 +1101,7 @@ impl SettingsWindow { page[header_index] = true; page[item_index] = true; } + this.filter_matches_to_file(); let first_navbar_entry_index = this .visible_navbar_entries() .next() @@ -1032,13 +1123,13 @@ impl SettingsWindow { } fn build_ui(&mut self, cx: &mut Context) { - self.pages = self.current_file.pages(); + if self.pages.is_empty() { + self.pages = page_data::settings_data(); + } self.build_search_matches(); self.build_navbar(); - if !self.search_bar.read(cx).is_empty(cx) { - self.update_matches(cx); - } + self.update_matches(cx); cx.notify(); } @@ -1878,6 +1969,7 @@ mod test { impl SettingsPageItem { fn basic_item(title: &'static str, description: &'static str) -> Self { SettingsPageItem::SettingItem(SettingItem { + files: USER, title, description, field: Box::new(SettingField {