Add holding opt/alt for fast scrolling (#31056)

Alistair Smith created

Fixes #14612

This was a feature I dearly missed from VSCode, so adding this helped me
migrate to Zed without disrupting my workflow. I found that `4.0` was a
nice goldilocks multiplier and felt close/the same as the speed in
VSCode.

Release Notes:

- Added faster scrolling in the editor while holding opt/alt

Change summary

assets/settings/default.json         |  4 ++++
crates/editor/src/editor_settings.rs | 11 +++++++++++
crates/editor/src/element.rs         | 16 +++++++++++++++-
3 files changed, 30 insertions(+), 1 deletion(-)

Detailed changes

assets/settings/default.json 🔗

@@ -475,6 +475,10 @@
   // Scroll sensitivity multiplier. This multiplier is applied
   // to both the horizontal and vertical delta values while scrolling.
   "scroll_sensitivity": 1.0,
+  // Scroll sensitivity multiplier for fast scrolling. This multiplier is applied
+  // to both the horizontal and vertical delta values while scrolling. Fast scrolling
+  // happens when a user holds the alt or option key while scrolling.
+  "fast_scroll_sensitivity": 4.0,
   "relative_line_numbers": false,
   // If 'search_wrap' is disabled, search result do not wrap around the end of the file.
   "search_wrap": true,

crates/editor/src/editor_settings.rs 🔗

@@ -26,6 +26,7 @@ pub struct EditorSettings {
     pub autoscroll_on_clicks: bool,
     pub horizontal_scroll_margin: f32,
     pub scroll_sensitivity: f32,
+    pub fast_scroll_sensitivity: f32,
     pub relative_line_numbers: bool,
     pub seed_search_query_from_cursor: SeedQuerySetting,
     pub use_smartcase_search: bool,
@@ -406,6 +407,12 @@ pub struct EditorSettingsContent {
     ///
     /// Default: 1.0
     pub scroll_sensitivity: Option<f32>,
+    /// Scroll sensitivity multiplier for fast scrolling. This multiplier is applied
+    /// to both the horizontal and vertical delta values while scrolling. Fast scrolling
+    /// happens when a user holds the alt or option key while scrolling.
+    ///
+    /// Default: 4.0
+    pub fast_scroll_sensitivity: Option<f32>,
     /// Whether the line numbers on editors gutter are relative or not.
     ///
     /// Default: false
@@ -745,6 +752,10 @@ impl Settings for EditorSettings {
             "editor.mouseWheelScrollSensitivity",
             &mut current.scroll_sensitivity,
         );
+        vscode.f32_setting(
+            "editor.fastScrollSensitivity",
+            &mut current.fast_scroll_sensitivity,
+        );
         if Some("relative") == vscode.read_string("editor.lineNumbers") {
             current.relative_line_numbers = Some(true);
         }

crates/editor/src/element.rs 🔗

@@ -6339,9 +6339,23 @@ impl EditorElement {
 
             // Set a minimum scroll_sensitivity of 0.01 to make sure the user doesn't
             // accidentally turn off their scrolling.
-            let scroll_sensitivity = EditorSettings::get_global(cx).scroll_sensitivity.max(0.01);
+            let base_scroll_sensitivity =
+                EditorSettings::get_global(cx).scroll_sensitivity.max(0.01);
+
+            // Use a minimum fast_scroll_sensitivity for same reason above
+            let fast_scroll_sensitivity = EditorSettings::get_global(cx)
+                .fast_scroll_sensitivity
+                .max(0.01);
 
             move |event: &ScrollWheelEvent, phase, window, cx| {
+                let scroll_sensitivity = {
+                    if event.modifiers.alt {
+                        fast_scroll_sensitivity
+                    } else {
+                        base_scroll_sensitivity
+                    }
+                };
+
                 if phase == DispatchPhase::Bubble && hitbox.is_hovered(window) {
                     delta = delta.coalesce(event.delta);
                     editor.update(cx, |editor, cx| {