Merge branch 'main' into setting-store

Max Brunsfeld created

Change summary

.github/workflows/ci.yml             |  1 
Cargo.lock                           | 66 ++++++++++++++---------------
assets/settings/default.json         | 13 +++++
crates/editor/src/editor.rs          |  9 ++++
crates/editor/src/editor_settings.rs | 12 +++++
crates/editor/src/element.rs         | 63 ++++++++++++++++++++++++++-
crates/gpui/Cargo.toml               |  2 
crates/zed/Cargo.toml                |  2 
8 files changed, 127 insertions(+), 41 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -1362,6 +1362,12 @@ dependencies = [
  "crossbeam-utils 0.8.15",
 ]
 
+[[package]]
+name = "const-cstr"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed3d0b5ff30645a68f35ece8cea4556ca14ef8a1651455f789a099a0513532a6"
+
 [[package]]
 name = "context_menu"
 version = "0.1.0"
@@ -1973,6 +1979,15 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "dlib"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794"
+dependencies = [
+ "libloading",
+]
+
 [[package]]
 name = "dotenvy"
 version = "0.15.7"
@@ -2175,16 +2190,6 @@ version = "2.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
 
-[[package]]
-name = "expat-sys"
-version = "2.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa"
-dependencies = [
- "cmake",
- "pkg-config",
-]
-
 [[package]]
 name = "fallible-iterator"
 version = "0.2.0"
@@ -2321,8 +2326,8 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
 [[package]]
 name = "font-kit"
-version = "0.10.0"
-source = "git+https://github.com/zed-industries/font-kit?rev=8eaf7a918eafa28b0a37dc759e2e0e7683fa24f1#8eaf7a918eafa28b0a37dc759e2e0e7683fa24f1"
+version = "0.11.0"
+source = "git+https://github.com/zed-industries/font-kit?rev=b2f77d56f450338aa4f7dd2f0197d8c9acb0cf18#b2f77d56f450338aa4f7dd2f0197d8c9acb0cf18"
 dependencies = [
  "bitflags",
  "byteorder",
@@ -2338,9 +2343,9 @@ dependencies = [
  "log",
  "pathfinder_geometry",
  "pathfinder_simd",
- "servo-fontconfig",
  "walkdir",
  "winapi 0.3.9",
+ "yeslogic-fontconfig-sys",
 ]
 
 [[package]]
@@ -6097,27 +6102,6 @@ dependencies = [
  "yaml-rust",
 ]
 
-[[package]]
-name = "servo-fontconfig"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7e3e22fe5fd73d04ebf0daa049d3efe3eae55369ce38ab16d07ddd9ac5c217c"
-dependencies = [
- "libc",
- "servo-fontconfig-sys",
-]
-
-[[package]]
-name = "servo-fontconfig-sys"
-version = "5.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e36b879db9892dfa40f95da1c38a835d41634b825fbd8c4c418093d53c24b388"
-dependencies = [
- "expat-sys",
- "freetype-sys",
- "pkg-config",
-]
-
 [[package]]
 name = "settings"
 version = "0.1.0"
@@ -8757,9 +8741,21 @@ version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
 
+[[package]]
+name = "yeslogic-fontconfig-sys"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2bbd69036d397ebbff671b1b8e4d918610c181c5a16073b96f984a38d08c386"
+dependencies = [
+ "const-cstr",
+ "dlib",
+ "once_cell",
+ "pkg-config",
+]
+
 [[package]]
 name = "zed"
-version = "0.87.0"
+version = "0.88.0"
 dependencies = [
  "activity_indicator",
  "anyhow",

assets/settings/default.json 🔗

@@ -52,6 +52,19 @@
   // 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",
   // 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 🔗

@@ -524,6 +524,15 @@ pub struct EditorSnapshot {
     ongoing_scroll: OngoingScroll,
 }
 
+impl EditorSnapshot {
+    fn has_scrollbar_info(&self) -> bool {
+        self.buffer_snapshot
+            .git_diff_hunks_in_range(0..self.max_point().row(), false)
+            .next()
+            .is_some()
+    }
+}
+
 #[derive(Clone, Debug)]
 struct SelectionHistoryEntry {
     selections: Arc<[Selection<Anchor>]>,

crates/editor/src/editor_settings.rs 🔗

@@ -7,6 +7,17 @@ pub struct EditorSettings {
     pub cursor_blink: bool,
     pub hover_popover_enabled: bool,
     pub show_completions_on_input: bool,
+    pub show_scrollbars: ShowScrollbars,
+}
+
+#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Default)]
+#[serde(rename_all = "snake_case")]
+pub enum ShowScrollbars {
+    #[default]
+    Auto,
+    System,
+    Always,
+    Never,
 }
 
 #[derive(Clone, Serialize, Deserialize, JsonSchema)]
@@ -14,6 +25,7 @@ pub struct EditorSettingsContent {
     pub cursor_blink: Option<bool>,
     pub hover_popover_enabled: Option<bool>,
     pub show_completions_on_input: Option<bool>,
+    pub show_scrollbars: Option<ShowScrollbars>,
 }
 
 impl Setting for EditorSettings {

crates/editor/src/element.rs 🔗

@@ -5,6 +5,7 @@ use super::{
 };
 use crate::{
     display_map::{BlockStyle, DisplaySnapshot, FoldStatus, TransformBlock},
+    editor_settings::ShowScrollbars,
     git::{diff_hunk_to_display, DisplayDiffHunk},
     hover_popover::{
         hide_hover, hover_at, HOVER_POPOVER_GAP, MIN_POPOVER_CHARACTER_WIDTH,
@@ -13,7 +14,7 @@ use crate::{
     link_go_to_definition::{
         go_to_fetched_definition, go_to_fetched_type_definition, update_go_to_definition_link,
     },
-    mouse_context_menu, EditorStyle, GutterHover, UnfoldAt,
+    mouse_context_menu, EditorSettings, EditorStyle, GutterHover, UnfoldAt,
 };
 use clock::ReplicaId;
 use collections::{BTreeMap, HashMap};
@@ -1026,15 +1027,16 @@ impl EditorElement {
         let mut first_row_y_offset = 0.0;
 
         // Impose a minimum height on the scrollbar thumb
+        let row_height = height / max_row;
         let min_thumb_height =
             style.min_height_factor * cx.font_cache.line_height(self.style.text.font_size);
-        let thumb_height = (row_range.end - row_range.start) * height / max_row;
+        let thumb_height = (row_range.end - row_range.start) * row_height;
         if thumb_height < min_thumb_height {
             first_row_y_offset = (min_thumb_height - thumb_height) / 2.0;
             height -= min_thumb_height - thumb_height;
         }
 
-        let y_for_row = |row: f32| -> f32 { top + first_row_y_offset + row * height / max_row };
+        let y_for_row = |row: f32| -> f32 { top + first_row_y_offset + row * row_height };
 
         let thumb_top = y_for_row(row_range.start) - first_row_y_offset;
         let thumb_bottom = y_for_row(row_range.end) + first_row_y_offset;
@@ -1048,6 +1050,50 @@ impl EditorElement {
                 background: style.track.background_color,
                 ..Default::default()
             });
+
+            let diff_style = theme::current(cx).editor.diff.clone();
+            for hunk in layout
+                .position_map
+                .snapshot
+                .buffer_snapshot
+                .git_diff_hunks_in_range(0..(max_row.floor() as u32), false)
+            {
+                let start_y = y_for_row(hunk.buffer_range.start as f32);
+                let mut end_y = if hunk.buffer_range.start == hunk.buffer_range.end {
+                    y_for_row((hunk.buffer_range.end + 1) as f32)
+                } else {
+                    y_for_row((hunk.buffer_range.end) as f32)
+                };
+
+                if end_y - start_y < 1. {
+                    end_y = start_y + 1.;
+                }
+                let bounds = RectF::from_points(vec2f(left, start_y), vec2f(right, end_y));
+
+                let color = match hunk.status() {
+                    DiffHunkStatus::Added => diff_style.inserted,
+                    DiffHunkStatus::Modified => diff_style.modified,
+                    DiffHunkStatus::Removed => diff_style.deleted,
+                };
+
+                let border = Border {
+                    width: 1.,
+                    color: style.thumb.border.color,
+                    overlay: false,
+                    top: false,
+                    right: true,
+                    bottom: false,
+                    left: true,
+                };
+
+                scene.push_quad(Quad {
+                    bounds,
+                    background: Some(color),
+                    border,
+                    corner_radius: style.thumb.corner_radius,
+                })
+            }
+
             scene.push_quad(Quad {
                 bounds: thumb_bounds,
                 border: style.thumb.border,
@@ -2014,7 +2060,16 @@ impl Element<Editor> for EditorElement {
             ));
         }
 
-        let show_scrollbars = editor.scroll_manager.scrollbars_visible();
+        let show_scrollbars =
+            match settings::get_setting::<EditorSettings>(None, cx).show_scrollbars {
+                ShowScrollbars::Auto => {
+                    snapshot.has_scrollbar_info() || editor.scroll_manager.scrollbars_visible()
+                }
+                ShowScrollbars::System => editor.scroll_manager.scrollbars_visible(),
+                ShowScrollbars::Always => true,
+                ShowScrollbars::Never => false,
+            };
+
         let include_root = editor
             .project
             .as_ref()

crates/gpui/Cargo.toml 🔗

@@ -72,7 +72,7 @@ cocoa = "0.24"
 core-foundation = { version = "0.9.3", features = ["with-uuid"] }
 core-graphics = "0.22.3"
 core-text = "19.2"
-font-kit = { git = "https://github.com/zed-industries/font-kit", rev = "8eaf7a918eafa28b0a37dc759e2e0e7683fa24f1" }
+font-kit = { git = "https://github.com/zed-industries/font-kit", rev = "b2f77d56f450338aa4f7dd2f0197d8c9acb0cf18" }
 foreign-types = "0.3"
 log.workspace = true
 metal = "0.21.0"

crates/zed/Cargo.toml 🔗

@@ -3,7 +3,7 @@ authors = ["Nathan Sobo <nathansobo@gmail.com>"]
 description = "The fast, collaborative code editor."
 edition = "2021"
 name = "zed"
-version = "0.87.0"
+version = "0.88.0"
 publish = false
 
 [lib]