Backport #2507 into preview (#2508)

Mikayla Maki created

This PR is a re-implementation of
https://github.com/zed-industries/zed/pull/2507, but in the old
global-settings style. Note that this PR is based on the 0.87.x branch,
and should be merged in along with the cherry-pick that includes
https://github.com/zed-industries/zed/pull/2504

Release Notes:

* N/A

Change summary

assets/settings/default.json    | 31 ++++++++++++++++++-------------
crates/editor/src/editor.rs     |  6 ------
crates/editor/src/element.rs    | 19 +++++++++++--------
crates/settings/src/settings.rs | 18 ++++++++++++------
4 files changed, 41 insertions(+), 33 deletions(-)

Detailed changes

assets/settings/default.json 🔗

@@ -43,19 +43,24 @@
   // 3. Draw all invisible symbols:
   //   "all"
   "show_whitespaces": "selection",
-  // Whether to show the scrollbar in the editor.
-  // This setting can take four values:
-  //
-  // 1. Show the scrollbar if there's important information or
-  //    follow the system's configured behavior (default):
-  //   "auto"
-  // 2. Match the system's configured behavior:
-  //    "system"
-  // 3. Always show the scrollbar:
-  //    "always"
-  // 4. Never show the scrollbar:
-  //    "never"
-  "show_scrollbars": "auto",
+  // Scrollbar related settings
+  "scrollbar": {
+      // When to show the scrollbar in the editor.
+      // This setting can take four values:
+      //
+      // 1. Show the scrollbar if there's important information or
+      //    follow the system's configured behavior (default):
+      //   "auto"
+      // 2. Match the system's configured behavior:
+      //    "system"
+      // 3. Always show the scrollbar:
+      //    "always"
+      // 4. Never show the scrollbar:
+      //    "never"
+      "show": "auto",
+      // Whether to show git diff indicators in the scrollbar.
+      "git_diff": true
+   },
   // Whether the screen sharing icon is shown in the os status bar.
   "show_call_status_icon": true,
   // Whether to use language servers to provide code intelligence.

crates/editor/src/editor.rs 🔗

@@ -517,12 +517,6 @@ pub struct EditorSnapshot {
     ongoing_scroll: OngoingScroll,
 }
 
-impl EditorSnapshot {
-    fn has_scrollbar_info(&self, is_singleton: bool) -> bool {
-        is_singleton && self.buffer_snapshot.has_git_diffs()
-    }
-}
-
 #[derive(Clone, Debug)]
 struct SelectionHistoryEntry {
     selections: Arc<[Selection<Anchor>]>,

crates/editor/src/element.rs 🔗

@@ -1047,7 +1047,7 @@ impl EditorElement {
                 ..Default::default()
             });
 
-            if layout.is_singleton {
+            if layout.is_singleton && cx.global::<Settings>().scrollbar.git_diff.unwrap_or(true) {
                 let diff_style = cx.global::<Settings>().theme.editor.diff.clone();
                 for hunk in layout
                     .position_map
@@ -2065,14 +2065,17 @@ impl Element<Editor> for EditorElement {
             ));
         }
 
-        let show_scrollbars = match cx.global::<Settings>().show_scrollbars {
-            settings::ShowScrollbars::Auto => {
-                snapshot.has_scrollbar_info(is_singleton)
-                    || editor.scroll_manager.scrollbars_visible()
+        let scrollbar_settings = cx.global::<Settings>().scrollbar;
+        let show_scrollbars = match scrollbar_settings.show.unwrap_or_default() {
+            settings::ShowScrollbar::Auto => {
+                // Git
+                (is_singleton && scrollbar_settings.git_diff.unwrap_or(true) && snapshot.buffer_snapshot.has_git_diffs())
+                // Scrollmanager
+                || editor.scroll_manager.scrollbars_visible()
             }
-            settings::ShowScrollbars::System => editor.scroll_manager.scrollbars_visible(),
-            settings::ShowScrollbars::Always => true,
-            settings::ShowScrollbars::Never => false,
+            settings::ShowScrollbar::System => editor.scroll_manager.scrollbars_visible(),
+            settings::ShowScrollbar::Always => true,
+            settings::ShowScrollbar::Never => false,
         };
 
         let include_root = editor

crates/settings/src/settings.rs 🔗

@@ -46,7 +46,7 @@ pub struct Settings {
     pub hover_popover_enabled: bool,
     pub show_completions_on_input: bool,
     pub show_call_status_icon: bool,
-    pub show_scrollbars: ShowScrollbars,
+    pub scrollbar: Scrollbar,
     pub vim_mode: bool,
     pub autosave: Autosave,
     pub default_dock_anchor: DockAnchor,
@@ -69,9 +69,15 @@ pub struct Settings {
     pub base_keymap: BaseKeymap,
 }
 
+#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Default)]
+pub struct Scrollbar {
+    pub show: Option<ShowScrollbar>,
+    pub git_diff: Option<bool>,
+}
+
 #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Default)]
 #[serde(rename_all = "snake_case")]
-pub enum ShowScrollbars {
+pub enum ShowScrollbar {
     #[default]
     Auto,
     System,
@@ -401,7 +407,7 @@ pub struct SettingsFileContent {
     #[serde(default)]
     pub active_pane_magnification: Option<f32>,
     #[serde(default)]
-    pub show_scrollbars: Option<ShowScrollbars>,
+    pub scrollbar: Option<Scrollbar>,
     #[serde(default)]
     pub cursor_blink: Option<bool>,
     #[serde(default)]
@@ -560,7 +566,7 @@ impl Settings {
             features: Features {
                 copilot: defaults.features.copilot.unwrap(),
             },
-            show_scrollbars: defaults.show_scrollbars.unwrap(),
+            scrollbar: defaults.scrollbar.unwrap(),
         }
     }
 
@@ -612,7 +618,7 @@ impl Settings {
         merge(&mut self.autosave, data.autosave);
         merge(&mut self.default_dock_anchor, data.default_dock_anchor);
         merge(&mut self.base_keymap, data.base_keymap);
-        merge(&mut self.show_scrollbars, data.show_scrollbars);
+        merge(&mut self.scrollbar, data.scrollbar);
         merge(&mut self.features.copilot, data.features.copilot);
 
         if let Some(copilot) = data.copilot {
@@ -845,7 +851,7 @@ impl Settings {
             auto_update: true,
             base_keymap: Default::default(),
             features: Features { copilot: true },
-            show_scrollbars: Default::default(),
+            scrollbar: Default::default(),
         }
     }