settings ui: Add new batch of settings (#39650)

Danilo Leal created

Release Notes:

- N/A

Change summary

crates/settings/src/settings_content.rs           |   41 
crates/settings/src/settings_content/workspace.rs |   13 
crates/settings_ui/src/page_data.rs               | 1279 +++++++++++++++-
crates/settings_ui/src/settings_ui.rs             |   14 
4 files changed, 1,248 insertions(+), 99 deletions(-)

Detailed changes

crates/settings/src/settings_content.rs 🔗

@@ -397,7 +397,19 @@ pub enum SteppingGranularity {
     Instruction,
 }
 
-#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
+#[derive(
+    Copy,
+    Clone,
+    Debug,
+    Serialize,
+    Deserialize,
+    JsonSchema,
+    MergeFrom,
+    PartialEq,
+    Eq,
+    strum::VariantArray,
+    strum::VariantNames,
+)]
 #[serde(rename_all = "snake_case")]
 pub enum DockPosition {
     Left,
@@ -571,7 +583,18 @@ pub struct FileFinderSettingsContent {
 }
 
 #[derive(
-    Debug, PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema, MergeFrom,
+    Debug,
+    PartialEq,
+    Eq,
+    Clone,
+    Copy,
+    Default,
+    Serialize,
+    Deserialize,
+    JsonSchema,
+    MergeFrom,
+    strum::VariantArray,
+    strum::VariantNames,
 )]
 #[serde(rename_all = "lowercase")]
 pub enum FileFinderWidthContent {
@@ -733,7 +756,19 @@ pub enum DockSide {
     Right,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize, Serialize, JsonSchema, MergeFrom)]
+#[derive(
+    Copy,
+    Clone,
+    Debug,
+    PartialEq,
+    Eq,
+    Deserialize,
+    Serialize,
+    JsonSchema,
+    MergeFrom,
+    strum::VariantArray,
+    strum::VariantNames,
+)]
 #[serde(rename_all = "snake_case")]
 pub enum ShowIndentGuides {
     Always,

crates/settings/src/settings_content/workspace.rs 🔗

@@ -541,7 +541,18 @@ pub struct ProjectPanelSettingsContent {
 }
 
 #[derive(
-    Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
+    Copy,
+    Clone,
+    Debug,
+    Default,
+    Serialize,
+    Deserialize,
+    JsonSchema,
+    MergeFrom,
+    PartialEq,
+    Eq,
+    strum::VariantArray,
+    strum::VariantNames,
 )]
 #[serde(rename_all = "snake_case")]
 pub enum ProjectPanelEntrySpacing {

crates/settings_ui/src/page_data.rs 🔗

@@ -1256,6 +1256,112 @@ pub(crate) fn user_settings_data() -> Vec<SettingsPage> {
                 //     }),
                 //     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,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Quick Actions",
+                    description: "Whether to show quick action buttons",
+                    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,
+                }),
+                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,
+                }),
+                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,
+                }),
+                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,
+                }),
             ],
         },
         SettingsPage {
@@ -1270,219 +1376,1202 @@ pub(crate) fn user_settings_data() -> Vec<SettingsPage> {
                                 .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: "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("Workbench"),
+                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
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Active Language Button",
+                    description: "Whether to show the active language button in the status bar",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(status_bar) = &settings_content.status_bar {
+                                &status_bar.active_language_button
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .status_bar
+                                .get_or_insert_default()
+                                .active_language_button
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Cursor Position Button",
+                    description: "Whether to show the cursor position button in the status bar",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(status_bar) = &settings_content.status_bar {
+                                &status_bar.cursor_position_button
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .status_bar
+                                .get_or_insert_default()
+                                .cursor_position_button
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SectionHeader("Terminal"),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Terminal Button",
+                    description: "Whether to show the terminal button in the status bar",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(terminal) = &settings_content.terminal {
+                                &terminal.button
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content.terminal.get_or_insert_default().button
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    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| {
+                            if let Some(tab_bar) = &settings_content.tab_bar {
+                                &tab_bar.show_nav_history_buttons
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .tab_bar
+                                .get_or_insert_default()
+                                .show_nav_history_buttons
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SectionHeader("Title Bar"),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Show Branch Icon",
+                    description: "Whether to show the branch icon beside branch switcher in the titlebar",
+                    field: Box::new(SettingField {
+                        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
+                                .title_bar
+                                .get_or_insert_default()
+                                .show_branch_icon
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Show Branch Name",
+                    description: "Whether to show the branch name button in the titlebar",
+                    field: Box::new(SettingField {
+                        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
+                                .title_bar
+                                .get_or_insert_default()
+                                .show_branch_name
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Show Project Items",
+                    description: "Whether to show the project host and name in the titlebar",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(title_bar) = &settings_content.title_bar {
+                                &title_bar.show_project_items
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .title_bar
+                                .get_or_insert_default()
+                                .show_project_items
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Show Onboarding Banner",
+                    description: "Whether to show onboarding banners in the titlebar",
+                    field: Box::new(SettingField {
+                        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
+                                .title_bar
+                                .get_or_insert_default()
+                                .show_onboarding_banner
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Show User Picture",
+                    description: "Whether to show user picture in the titlebar",
+                    field: Box::new(SettingField {
+                        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
+                                .title_bar
+                                .get_or_insert_default()
+                                .show_user_picture
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Show Sign In",
+                    description: "Whether to show the sign in button in the titlebar",
+                    field: Box::new(SettingField {
+                        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
+                                .title_bar
+                                .get_or_insert_default()
+                                .show_sign_in
+                        },
+                    }),
+                    metadata: None,
+                }),
+                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
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SectionHeader("Search Settings"),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Search Button",
+                    description: "Whether to show the project search button in the status bar",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(search) = &settings_content.editor.search {
+                                &search.button
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .editor
+                                .search
+                                .get_or_insert_default()
+                                .button
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Whole Word",
+                    description: "Whether to search for whole words by default",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(search) = &settings_content.editor.search {
+                                &search.whole_word
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .editor
+                                .search
+                                .get_or_insert_default()
+                                .whole_word
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Case Sensitive",
+                    description: "Whether to search case-sensitively by default",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(search) = &settings_content.editor.search {
+                                &search.case_sensitive
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .editor
+                                .search
+                                .get_or_insert_default()
+                                .case_sensitive
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Include Ignored",
+                    description: "Whether to include ignored files in search results by default",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(search) = &settings_content.editor.search {
+                                &search.include_ignored
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .editor
+                                .search
+                                .get_or_insert_default()
+                                .include_ignored
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Regex",
+                    description: "Whether to use regex search by default",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(search) = &settings_content.editor.search {
+                                &search.regex
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content.editor.search.get_or_insert_default().regex
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SectionHeader("File Finder"),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "File Icons",
+                    description: "Whether to show file icons in the file finder",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(file_finder) = &settings_content.file_finder {
+                                &file_finder.file_icons
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .file_finder
+                                .get_or_insert_default()
+                                .file_icons
+                        },
+                    }),
+                    metadata: None,
+                }),
+                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",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(file_finder) = &settings_content.file_finder {
+                                &file_finder.modal_max_width
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .file_finder
+                                .get_or_insert_default()
+                                .modal_max_width
+                        },
+                    }),
+                    metadata: None,
+                }),
+                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",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            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
+                                .file_finder
+                                .get_or_insert_default()
+                                .skip_focus_for_active_in_search
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Git Status",
+                    description: "Whether to show the git status in the file finder",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(file_finder) = &settings_content.file_finder {
+                                &file_finder.git_status
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .file_finder
+                                .get_or_insert_default()
+                                .git_status
+                        },
+                    }),
+                    metadata: None,
+                }),
+                // 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 & Tools",
+            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::SettingItem(SettingItem {
+                    title: "Entry Spacing",
+                    description: "Spacing between worktree entries in the project panel",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(project_panel) = &settings_content.project_panel {
+                                &project_panel.entry_spacing
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .project_panel
+                                .get_or_insert_default()
+                                .entry_spacing
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    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(project_panel) = &settings_content.project_panel {
+                                &project_panel.file_icons
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .project_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 project panel",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(project_panel) = &settings_content.project_panel {
+                                &project_panel.folder_icons
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .project_panel
+                                .get_or_insert_default()
+                                .folder_icons
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Git Status",
+                    description: "Whether to show the git status in the project panel",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(project_panel) = &settings_content.project_panel {
+                                &project_panel.git_status
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .project_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(project_panel) = &settings_content.project_panel {
+                                &project_panel.indent_size
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .project_panel
+                                .get_or_insert_default()
+                                .indent_size
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    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(project_panel) = &settings_content.project_panel {
+                                &project_panel.auto_reveal_entries
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .project_panel
+                                .get_or_insert_default()
+                                .auto_reveal_entries
+                        },
+                    }),
+                    metadata: None,
+                }),
+                SettingsPageItem::SettingItem(SettingItem {
+                    title: "Starts Open",
+                    description: "Whether the project panel should open on startup",
+                    field: Box::new(SettingField {
+                        pick: |settings_content| {
+                            if let Some(project_panel) = &settings_content.project_panel {
+                                &project_panel.starts_open
+                            } else {
+                                &None
+                            }
+                        },
+                        pick_mut: |settings_content| {
+                            &mut settings_content
+                                .project_panel
+                                .get_or_insert_default()
+                                .starts_open
+                        },
+                    }),
+                    metadata: None,
+                }),
+                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",
+                    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
+                        },
                     }),
-                    SettingsPageItem::SubPageLink(SubPageLink {
-                        title: "Rust",
-                        render: Arc::new(|this, window, cx| {
-                            this.render_page_items(language_settings_data().iter(), window, cx)
-                                .into_any_element()
-                        }),
+                    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
+                        },
                     }),
-                    SettingsPageItem::SubPageLink(SubPageLink {
-                        title: "Python",
-                        render: Arc::new(|this, window, cx| {
-                            this.render_page_items(language_settings_data().iter(), window, cx)
-                                .into_any_element()
-                        }),
+                    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
+                        },
                     }),
-                    SettingsPageItem::SubPageLink(SubPageLink {
-                        title: "TSX",
-                        render: Arc::new(|this, window, cx| {
-                            this.render_page_items(language_settings_data().iter(), window, cx)
-                                .into_any_element()
-                        }),
+                    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
+                        },
                     }),
-                ];
-
-                items.push(SettingsPageItem::SectionHeader("Default Language Settings"));
-                items.extend(language_settings_data());
-
-                items
-            },
-        },
-        SettingsPage {
-            title: "Workbench & Window",
-            items: vec![
-                SettingsPageItem::SectionHeader("Workbench"),
+                    metadata: None,
+                }),
                 SettingsPageItem::SettingItem(SettingItem {
-                    title: "Editor Tabs",
-                    description: "Whether or not to show the tab bar 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(tab_bar) = &settings_content.tab_bar {
-                                &tab_bar.show
+                            if let Some(outline_panel) = &settings_content.outline_panel {
+                                &outline_panel.default_width
                             } 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()
+                                .default_width
                         },
                     }),
                     metadata: None,
                 }),
                 SettingsPageItem::SettingItem(SettingItem {
-                    title: "Active language Button",
-                    description: "Whether to show the active language button in the status bar",
+                    title: "File Icons",
+                    description: "Whether to show file icons in the outline 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(outline_panel) = &settings_content.outline_panel {
+                                &outline_panel.file_icons
                             } else {
                                 &None
                             }
                         },
                         pick_mut: |settings_content| {
                             &mut settings_content
-                                .status_bar
+                                .outline_panel
                                 .get_or_insert_default()
-                                .active_language_button
+                                .file_icons
                         },
                     }),
                     metadata: None,
                 }),
                 SettingsPageItem::SettingItem(SettingItem {
-                    title: "Cursor Position Button",
-                    description: "Whether to show the cursor position button in the status bar",
+                    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(status_bar) = &settings_content.status_bar {
-                                &status_bar.cursor_position_button
+                            if let Some(outline_panel) = &settings_content.outline_panel {
+                                &outline_panel.folder_icons
                             } else {
                                 &None
                             }
                         },
                         pick_mut: |settings_content| {
                             &mut settings_content
-                                .status_bar
+                                .outline_panel
                                 .get_or_insert_default()
-                                .cursor_position_button
+                                .folder_icons
                         },
                     }),
                     metadata: None,
                 }),
-                SettingsPageItem::SectionHeader("Terminal"),
                 SettingsPageItem::SettingItem(SettingItem {
-                    title: "Terminal Button",
-                    description: "Whether to show the terminal button in the status bar",
+                    title: "Git Status",
+                    description: "Whether to show the git status in the outline panel",
                     field: Box::new(SettingField {
                         pick: |settings_content| {
-                            if let Some(terminal) = &settings_content.terminal {
-                                &terminal.button
+                            if let Some(outline_panel) = &settings_content.outline_panel {
+                                &outline_panel.git_status
                             } else {
                                 &None
                             }
                         },
                         pick_mut: |settings_content| {
-                            &mut settings_content.terminal.get_or_insert_default().button
+                            &mut settings_content
+                                .outline_panel
+                                .get_or_insert_default()
+                                .git_status
                         },
                     }),
                     metadata: None,
                 }),
                 SettingsPageItem::SettingItem(SettingItem {
-                    title: "Show Navigation History Buttons",
-                    description: "Whether or not to show the navigation history buttons in the tab bar",
+                    title: "Indent Size",
+                    description: "Amount of indentation for nested items",
                     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(outline_panel) = &settings_content.outline_panel {
+                                &outline_panel.indent_size
                             } else {
                                 &None
                             }
                         },
                         pick_mut: |settings_content| {
                             &mut settings_content
-                                .tab_bar
+                                .outline_panel
                                 .get_or_insert_default()
-                                .show_nav_history_buttons
+                                .indent_size
                         },
                     }),
                     metadata: None,
                 }),
-            ],
-        },
-        SettingsPage {
-            title: "Panels & Tools",
-            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",
+                    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(project_panel) = &settings_content.project_panel {
-                                &project_panel.button
+                            if let Some(outline_panel) = &settings_content.outline_panel {
+                                &outline_panel.auto_reveal_entries
                             } else {
                                 &None
                             }
                         },
                         pick_mut: |settings_content| {
                             &mut settings_content
-                                .project_panel
+                                .outline_panel
                                 .get_or_insert_default()
-                                .button
+                                .auto_reveal_entries
                         },
                     }),
                     metadata: None,
                 }),
                 SettingsPageItem::SettingItem(SettingItem {
-                    title: "Project Panel Dock",
-                    description: "Where to dock the project panel",
+                    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(project_panel) = &settings_content.project_panel {
-                                &project_panel.dock
+                            if let Some(outline_panel) = &settings_content.outline_panel {
+                                &outline_panel.auto_fold_dirs
                             } else {
                                 &None
                             }
                         },
                         pick_mut: |settings_content| {
-                            &mut settings_content.project_panel.get_or_insert_default().dock
+                            &mut settings_content
+                                .outline_panel
+                                .get_or_insert_default()
+                                .auto_fold_dirs
                         },
                     }),
                     metadata: None,
                 }),
-                // todo(settings_ui): Needs numeric stepper
                 // SettingsPageItem::SettingItem(SettingItem {
-                //     title: "Project Panel Default Width",
-                //     description: "Default width of the project panel in pixels",
+                //     title: "Indent Guides Show",
+                //     description: "When to show indent guides in the outline panel",
                 //     field: Box::new(SettingField {
                 //         pick: |settings_content| {
-                //             if let Some(project_panel) = &settings_content.project_panel {
-                //                 &project_panel.default_width
+                //             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
-                //                 .project_panel
+                //                 .outline_panel
+                //                 .get_or_insert_default()
+                //                 .indent_guides
                 //                 .get_or_insert_default()
-                //                 .default_width
+                //                 .show
                 //         },
                 //     }),
                 //     metadata: None,
                 // }),
-                SettingsPageItem::SectionHeader("Terminal"),
+                SettingsPageItem::SectionHeader("Notification Panel"),
                 SettingsPageItem::SettingItem(SettingItem {
-                    title: "Terminal Dock",
-                    description: "Where to dock the terminal panel",
+                    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(terminal) = &settings_content.terminal {
-                                &terminal.dock
+                            if let Some(notification_panel) = &settings_content.notification_panel {
+                                &notification_panel.button
                             } else {
                                 &None
                             }
                         },
                         pick_mut: |settings_content| {
-                            &mut settings_content.terminal.get_or_insert_default().dock
+                            &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 {
+                                &notification_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 {
+                                &notification_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,

crates/settings_ui/src/settings_ui.rs 🔗

@@ -278,6 +278,9 @@ fn init_renderers(cx: &mut App) {
         .add_renderer::<settings::TerminalDockPosition>(|settings_field, file, _, window, cx| {
             render_dropdown(*settings_field, file, window, cx)
         })
+        .add_renderer::<settings::DockPosition>(|settings_field, file, _, window, cx| {
+            render_dropdown(*settings_field, file, window, cx)
+        })
         .add_renderer::<settings::GitGutterSetting>(|settings_field, file, _, window, cx| {
             render_dropdown(*settings_field, file, window, cx)
         })
@@ -309,6 +312,11 @@ fn init_renderers(cx: &mut App) {
         .add_renderer::<settings::ShowCloseButton>(|settings_field, file, _, window, cx| {
             render_dropdown(*settings_field, file, window, cx)
         })
+        .add_renderer::<settings::ProjectPanelEntrySpacing>(
+            |settings_field, file, _, window, cx| {
+                render_dropdown(*settings_field, file, window, cx)
+            },
+        )
         .add_renderer::<settings::RewrapBehavior>(|settings_field, file, _, window, cx| {
             render_dropdown(*settings_field, file, window, cx)
         })
@@ -323,6 +331,12 @@ fn init_renderers(cx: &mut App) {
                 render_dropdown(*settings_field, file, window, cx)
             },
         )
+        .add_renderer::<settings::FileFinderWidthContent>(|settings_field, file, _, window, cx| {
+            render_dropdown(*settings_field, file, window, cx)
+        })
+        .add_renderer::<settings::ShowDiagnostics>(|settings_field, file, _, window, cx| {
+            render_dropdown(*settings_field, file, window, cx)
+        })
         .add_renderer::<settings::WordsCompletionMode>(|settings_field, file, _, window, cx| {
             render_dropdown(*settings_field, file, window, cx)
         })