Allow to hide more buttons with the settings (#30565)

Kirill Bulatov created

* project search button in the status bar
```jsonc
"search": {
  "button": false
},
```

* project diagnostics button in the status bar
```jsonc
"diagnostics": {
  "button": false
}
```

* project name and host buttons in the title bar
```jsonc
"title_bar": {
    "show_project_items": false
}
```

* git branch button in the title bar
```jsonc
"title_bar": {
    "show_branch_name": false
}
```

Before:
<img width="1728" alt="before"
src="https://github.com/user-attachments/assets/4b13b431-3ac1-43b3-8ac7-469e5a9ccf7e"
/>

After:
<img width="1728" alt="after"
src="https://github.com/user-attachments/assets/baf2765a-e27b-47a3-8897-89152b7a7c95"
/>


Release Notes:

- Added more settings to hide buttons from Zed UI

Change summary

assets/settings/default.json               |  8 ++++++
crates/diagnostics/src/items.rs            | 10 ++++++-
crates/editor/src/editor_settings.rs       |  4 +++
crates/project/src/project_settings.rs     | 16 ++++++------
crates/search/src/buffer_search.rs         |  2 +
crates/search/src/search_status_button.rs  |  9 ++++++
crates/title_bar/src/title_bar.rs          | 31 +++++++++++++++++------
crates/title_bar/src/title_bar_settings.rs | 16 ++++++++++++
8 files changed, 76 insertions(+), 20 deletions(-)

Detailed changes

assets/settings/default.json 🔗

@@ -328,6 +328,10 @@
   "title_bar": {
     // Whether to show the branch icon beside branch switcher in the titlebar.
     "show_branch_icon": false,
+    // Whether to show the branch name button in the titlebar.
+    "show_branch_name": true,
+    // Whether to show the project host and name in the titlebar.
+    "show_project_items": true,
     // Whether to show onboarding banners in the titlebar.
     "show_onboarding_banner": true,
     // Whether to show user picture in the titlebar.
@@ -470,6 +474,8 @@
   "search_wrap": true,
   // Search options to enable by default when opening new project and buffer searches.
   "search": {
+    // Whether to show the project search button in the status bar.
+    "button": true,
     "whole_word": false,
     "case_sensitive": false,
     "include_ignored": false,
@@ -1002,6 +1008,8 @@
   "auto_update": true,
   // Diagnostics configuration.
   "diagnostics": {
+    // Whether to show the project diagnostics button in the status bar.
+    "button": true,
     // Whether to show warnings or not by default.
     "include_warnings": true,
     // Settings for inline diagnostics

crates/diagnostics/src/items.rs 🔗

@@ -6,6 +6,8 @@ use gpui::{
     WeakEntity, Window,
 };
 use language::Diagnostic;
+use project::project_settings::ProjectSettings;
+use settings::Settings;
 use ui::{Button, ButtonLike, Color, Icon, IconName, Label, Tooltip, h_flex, prelude::*};
 use workspace::{StatusItemView, ToolbarItemEvent, Workspace, item::ItemHandle};
 
@@ -22,6 +24,11 @@ pub struct DiagnosticIndicator {
 
 impl Render for DiagnosticIndicator {
     fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
+        let indicator = h_flex().gap_2();
+        if !ProjectSettings::get_global(cx).diagnostics.button {
+            return indicator;
+        }
+
         let diagnostic_indicator = match (self.summary.error_count, self.summary.warning_count) {
             (0, 0) => h_flex().map(|this| {
                 this.child(
@@ -84,8 +91,7 @@ impl Render for DiagnosticIndicator {
             None
         };
 
-        h_flex()
-            .gap_2()
+        indicator
             .child(
                 ButtonLike::new("diagnostic-indicator")
                     .child(diagnostic_indicator)

crates/editor/src/editor_settings.rs 🔗

@@ -4,6 +4,7 @@ use project::project_settings::DiagnosticSeverity;
 use schemars::JsonSchema;
 use serde::{Deserialize, Serialize};
 use settings::{Settings, SettingsSources, VsCodeSettings};
+use util::serde::default_true;
 
 #[derive(Deserialize, Clone)]
 pub struct EditorSettings {
@@ -276,6 +277,9 @@ pub enum ScrollBeyondLastLine {
 /// Default options for buffer and project search items.
 #[derive(Copy, Clone, Default, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
 pub struct SearchSettings {
+    /// Whether to show the project search button in the status bar.
+    #[serde(default = "default_true")]
+    pub button: bool,
     #[serde(default)]
     pub whole_word: bool,
     #[serde(default)]

crates/project/src/project_settings.rs 🔗

@@ -119,11 +119,15 @@ pub enum DirenvSettings {
 
 #[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
 pub struct DiagnosticsSettings {
-    /// Whether or not to include warning diagnostics
-    #[serde(default = "true_value")]
+    /// Whether to show the project diagnostics button in the status bar.
+    #[serde(default = "default_true")]
+    pub button: bool,
+
+    /// Whether or not to include warning diagnostics.
+    #[serde(default = "default_true")]
     pub include_warnings: bool,
 
-    /// Settings for showing inline diagnostics
+    /// Settings for showing inline diagnostics.
     #[serde(default)]
     pub inline: InlineDiagnosticsSettings,
 
@@ -304,7 +308,7 @@ pub struct InlineBlameSettings {
     /// the currently focused line.
     ///
     /// Default: true
-    #[serde(default = "true_value")]
+    #[serde(default = "default_true")]
     pub enabled: bool,
     /// Whether to only show the inline blame information
     /// after a delay once the cursor stops moving.
@@ -322,10 +326,6 @@ pub struct InlineBlameSettings {
     pub show_commit_summary: bool,
 }
 
-const fn true_value() -> bool {
-    true
-}
-
 #[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
 pub struct BinarySettings {
     pub path: Option<String>,

crates/search/src/buffer_search.rs 🔗

@@ -2788,6 +2788,7 @@ mod tests {
         let (_editor, search_bar, cx) = init_test(cx);
         update_search_settings(
             SearchSettings {
+                button: true,
                 whole_word: false,
                 case_sensitive: false,
                 include_ignored: false,
@@ -2853,6 +2854,7 @@ mod tests {
 
         update_search_settings(
             SearchSettings {
+                button: true,
                 whole_word: false,
                 case_sensitive: true,
                 include_ignored: false,

crates/search/src/search_status_button.rs 🔗

@@ -1,3 +1,5 @@
+use editor::EditorSettings;
+use settings::Settings as _;
 use ui::{
     ButtonCommon, ButtonLike, Clickable, Color, Context, Icon, IconName, IconSize, ParentElement,
     Render, Styled, Tooltip, Window, h_flex,
@@ -14,7 +16,12 @@ impl SearchButton {
 
 impl Render for SearchButton {
     fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl ui::IntoElement {
-        h_flex().gap_2().child(
+        let button = h_flex().gap_2();
+        if !EditorSettings::get_global(cx).search.button {
+            return button;
+        }
+
+        button.child(
             ButtonLike::new("project-search-indicator")
                 .child(
                     Icon::new(IconName::MagnifyingGlass)

crates/title_bar/src/title_bar.rs 🔗

@@ -128,6 +128,7 @@ pub struct TitleBar {
 
 impl Render for TitleBar {
     fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
+        let title_bar_settings = *TitleBarSettings::get_global(cx);
         let close_action = Box::new(workspace::CloseWindow);
         let height = Self::height(window);
         let supported_controls = window.window_controls();
@@ -191,26 +192,38 @@ impl Render for TitleBar {
                         h_flex()
                             .gap_1()
                             .map(|title_bar| {
-                                let mut render_project_items = true;
+                                let mut render_project_items = title_bar_settings.show_branch_name
+                                    || title_bar_settings.show_project_items;
                                 title_bar
                                     .when_some(self.application_menu.clone(), |title_bar, menu| {
-                                        render_project_items = !menu.read(cx).all_menus_shown();
+                                        render_project_items &= !menu.read(cx).all_menus_shown();
                                         title_bar.child(menu)
                                     })
                                     .when(render_project_items, |title_bar| {
                                         title_bar
-                                            .children(self.render_project_host(cx))
-                                            .child(self.render_project_name(cx))
-                                            .children(self.render_project_branch(cx))
+                                            .when(
+                                                title_bar_settings.show_project_items,
+                                                |title_bar| {
+                                                    title_bar
+                                                        .children(self.render_project_host(cx))
+                                                        .child(self.render_project_name(cx))
+                                                },
+                                            )
+                                            .when(
+                                                title_bar_settings.show_branch_name,
+                                                |title_bar| {
+                                                    title_bar
+                                                        .children(self.render_project_branch(cx))
+                                                },
+                                            )
                                     })
                             })
                             .on_mouse_down(MouseButton::Left, |_, _, cx| cx.stop_propagation()),
                     )
                     .child(self.render_collaborator_list(window, cx))
-                    .when(
-                        TitleBarSettings::get_global(cx).show_onboarding_banner,
-                        |title_bar| title_bar.child(self.banner.clone()),
-                    )
+                    .when(title_bar_settings.show_onboarding_banner, |title_bar| {
+                        title_bar.child(self.banner.clone())
+                    })
                     .child(
                         h_flex()
                             .gap_1()

crates/title_bar/src/title_bar_settings.rs 🔗

@@ -2,11 +2,19 @@ use db::anyhow;
 use schemars::JsonSchema;
 use serde::{Deserialize, Serialize};
 use settings::{Settings, SettingsSources};
+use util::serde::default_true;
 
 #[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
 pub struct TitleBarSettings {
+    #[serde(default)]
     pub show_branch_icon: bool,
+    #[serde(default = "default_true")]
+    pub show_branch_name: bool,
+    #[serde(default = "default_true")]
+    pub show_project_items: bool,
+    #[serde(default = "default_true")]
     pub show_onboarding_banner: bool,
+    #[serde(default = "default_true")]
     pub show_user_picture: bool,
 }
 
@@ -24,6 +32,14 @@ pub struct TitleBarSettingsContent {
     ///
     /// Default: true
     pub show_user_picture: Option<bool>,
+    /// Whether to show the branch name button in the titlebar.
+    ///
+    /// Default: true
+    pub show_branch_name: Option<bool>,
+    /// Whether to show the project host and name in the titlebar.
+    ///
+    /// Default: true
+    pub show_project_items: Option<bool>,
 }
 
 impl Settings for TitleBarSettings {