Finished mouse compatability

Mikayla Maki created

Change summary

assets/settings/default.json          | 62 ++++++++++++++++------------
crates/settings/src/settings.rs       | 14 ++++++
crates/terminal/src/mappings/mouse.rs |  4 
crates/terminal/src/terminal.rs       | 11 ++++
crates/terminal/src/terminal_view.rs  | 16 +++++++
5 files changed, 77 insertions(+), 30 deletions(-)

Detailed changes

assets/settings/default.json 🔗

@@ -102,27 +102,37 @@
         //
         //
         "working_directory": "current_project_directory",
-        //Set the cursor blinking behavior in the terminal.
-        //May take 4 values:
-        // 1. Never blink the cursor, ignoring the terminal mode
-        //        "blinking": "off",
-        // 2. Default the cursor blink to off, but allow the terminal to 
-        //    set blinking
-        //        "blinking": "terminal_controlled",
-        // 3. Always blink the cursor, ignoring the terminal mode
-        //        "blinking": "on",
+        // Set the cursor blinking behavior in the terminal.
+        // May take 4 values:
+        //  1. Never blink the cursor, ignoring the terminal mode
+        //         "blinking": "off",
+        //  2. Default the cursor blink to off, but allow the terminal to 
+        //     set blinking
+        //         "blinking": "terminal_controlled",
+        //  3. Always blink the cursor, ignoring the terminal mode
+        //         "blinking": "on",
         "blinking": "terminal_controlled",
-        //Any key-value pairs added to this list will be added to the terminal's
-        //enviroment. Use `:` to seperate multiple values.
+        // Set whether Alternate Scroll mode (code: ?1007) is active by default.
+        // Alternate Scroll mode converts mouse scroll events into up / down key
+        // presses when in the alternate screen (e.g. when running applications 
+        // like vim or  less). The terminal can still set and unset this mode.
+        // May take 2 values:
+        //  1. Default alternate scroll mode to on
+        //         "alternate_scroll": "on",
+        //  2. Default alternate scroll mode to off
+        //         "alternate_scroll": "off",
+        "alternate_scroll": "off",
+        // Any key-value pairs added to this list will be added to the terminal's
+        // enviroment. Use `:` to seperate multiple values.
         "env": {
-            //"KEY": "value1:value2"
+            // "KEY": "value1:value2"
         }
-        //Set the terminal's font size. If this option is not included,
-        //the terminal will default to matching the buffer's font size.
-        //"font_size": "15"
-        //Set the terminal's font family. If this option is not included,
-        //the terminal will default to matching the buffer's font family.
-        //"font_family": "Zed Mono"
+        // Set the terminal's font size. If this option is not included,
+        // the terminal will default to matching the buffer's font size.
+        // "font_size": "15"
+        // Set the terminal's font family. If this option is not included,
+        // the terminal will default to matching the buffer's font family.
+        // "font_family": "Zed Mono"
     },
     // Different settings for specific languages.
     "languages": {
@@ -155,15 +165,15 @@
             "tab_size": 2
         }
     },
-    //LSP Specific settings.
+    // LSP Specific settings.
     "lsp": {
-        //Specify the LSP name as a key here.
-        //As of 8/10/22, supported LSPs are:
-        //pyright
-        //gopls
-        //rust-analyzer
-        //typescript-language-server
-        //vscode-json-languageserver
+        // Specify the LSP name as a key here.
+        // As of 8/10/22, supported LSPs are:
+        // pyright
+        // gopls
+        // rust-analyzer
+        // typescript-language-server
+        // vscode-json-languageserver
         // "rust_analyzer": {
         //     //These initialization options are merged into Zed's defaults
         //     "initialization_options": {

crates/settings/src/settings.rs 🔗

@@ -84,6 +84,7 @@ pub struct TerminalSettings {
     pub font_family: Option<String>,
     pub env: Option<HashMap<String, String>>,
     pub blinking: Option<TerminalBlink>,
+    pub alternate_scroll: Option<AlternateScroll>,
 }
 
 #[derive(Clone, Debug, Deserialize, PartialEq, Eq, JsonSchema)]
@@ -114,6 +115,19 @@ impl Default for Shell {
     }
 }
 
+#[derive(Clone, Debug, Deserialize, PartialEq, Eq, JsonSchema)]
+#[serde(rename_all = "snake_case")]
+pub enum AlternateScroll {
+    On,
+    Off,
+}
+
+impl Default for AlternateScroll {
+    fn default() -> Self {
+        AlternateScroll::On
+    }
+}
+
 #[derive(Clone, Debug, Deserialize, PartialEq, Eq, JsonSchema)]
 #[serde(rename_all = "snake_case")]
 pub enum WorkingDirectory {

crates/terminal/src/mappings/mouse.rs 🔗

@@ -134,8 +134,8 @@ pub fn scroll_report(
 pub fn alt_scroll(scroll_lines: i32) -> Vec<u8> {
     let cmd = if scroll_lines > 0 { b'A' } else { b'B' };
 
-    let mut content = Vec::with_capacity(scroll_lines as usize * 3);
-    for _ in 0..scroll_lines {
+    let mut content = Vec::with_capacity(scroll_lines.abs() as usize * 3);
+    for _ in 0..scroll_lines.abs() {
         content.push(0x1b);
         content.push(b'O');
         content.push(cmd);

crates/terminal/src/terminal.rs 🔗

@@ -28,7 +28,7 @@ use mappings::mouse::{
     alt_scroll, mouse_button_report, mouse_moved_report, mouse_point, mouse_side, scroll_report,
 };
 use modal::deploy_modal;
-use settings::{Settings, Shell, TerminalBlink};
+use settings::{AlternateScroll, Settings, Shell, TerminalBlink};
 use std::{collections::HashMap, fmt::Display, ops::Sub, path::PathBuf, sync::Arc, time::Duration};
 use thiserror::Error;
 
@@ -263,6 +263,7 @@ impl TerminalBuilder {
         env: Option<HashMap<String, String>>,
         initial_size: TerminalSize,
         blink_settings: Option<TerminalBlink>,
+        alternate_scroll: &AlternateScroll,
     ) -> Result<TerminalBuilder> {
         let pty_config = {
             let alac_shell = shell.clone().and_then(|shell| match shell {
@@ -306,6 +307,14 @@ impl TerminalBuilder {
             term.set_mode(alacritty_terminal::ansi::Mode::BlinkingCursor)
         }
 
+        //Start alternate_scroll if we need to
+        if let AlternateScroll::On = alternate_scroll {
+            term.set_mode(alacritty_terminal::ansi::Mode::AlternateScroll)
+        } else {
+            //Alacritty turns it on by default, so we need to turn it off.
+            term.unset_mode(alacritty_terminal::ansi::Mode::AlternateScroll)
+        }
+
         let term = Arc::new(FairMutex::new(term));
 
         //Setup the pty...

crates/terminal/src/terminal_view.rs 🔗

@@ -10,7 +10,7 @@ use workspace::{Item, Workspace};
 
 use crate::TerminalSize;
 use project::{LocalWorktree, Project, ProjectPath};
-use settings::{Settings, WorkingDirectory};
+use settings::{AlternateScroll, Settings, WorkingDirectory};
 use smallvec::SmallVec;
 use std::path::{Path, PathBuf};
 
@@ -94,12 +94,26 @@ impl TerminalView {
         let shell = settings.terminal_overrides.shell.clone();
         let envs = settings.terminal_overrides.env.clone(); //Should be short and cheap.
 
+        //TODO: move this pattern to settings
+        let scroll = settings
+            .terminal_overrides
+            .alternate_scroll
+            .as_ref()
+            .unwrap_or(
+                settings
+                    .terminal_defaults
+                    .alternate_scroll
+                    .as_ref()
+                    .unwrap_or_else(|| &AlternateScroll::On),
+            );
+
         let content = match TerminalBuilder::new(
             working_directory.clone(),
             shell,
             envs,
             size_info,
             settings.terminal_overrides.blinking.clone(),
+            scroll,
         ) {
             Ok(terminal) => {
                 let terminal = cx.add_model(|cx| terminal.subscribe(cx));