Upgrade alacritty_terminal in hopes to avoid PTY poll failing (#6715)

Thorsten Ball created

We saw stack traces in our #panic channel pop up that failed on this
line:


https://github.com/zed-industries/alacritty/blob/33306142195b354ef3485ca2b1d8a85dfc6605ca/alacritty_terminal/src/event_loop.rs#L323-L324

With this message:

thread 'PTY reader' panicked at 'called `Result::unwrap()` on an `Err`
value: Os { code: 9, kind: Uncategorized, message: "Bad file descriptor"
}'

/Users/administrator/.cargo/git/checkouts/alacritty-afea874b09a502a5/3330614/alacritty_terminal/src/event_loop.rs:324

We don't know how to reproduce the error. It doesn't seem related to the
number of open PTY handles, because `openpty` itself didn't fail. We can
only assume that something went wrong between `openpty` and the setup of
the polling.

Since Alacritty itself changed its polling mechanism significantly by
switching from `mio` to `polling`
(https://github.com/alacritty/alacritty/pull/6846) we upgraded with the
hope that this will fix the bug.


Release Notes:

- Upgraded alacritty_terminal to newest version in order to hopefully
fix a rare panic that can occur when starting a new terminal.

Change summary

Cargo.lock                                   | 239 +++++++--------------
crates/terminal/Cargo.toml                   |   2 
crates/terminal/src/mappings/colors.rs       |   5 
crates/terminal/src/terminal.rs              |  85 +++---
crates/terminal_view/src/terminal_element.rs |  13 
5 files changed, 136 insertions(+), 208 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -101,50 +101,25 @@ dependencies = [
  "util",
 ]
 
-[[package]]
-name = "alacritty_config"
-version = "0.1.2-dev"
-source = "git+https://github.com/zed-industries/alacritty?rev=33306142195b354ef3485ca2b1d8a85dfc6605ca#33306142195b354ef3485ca2b1d8a85dfc6605ca"
-dependencies = [
- "log",
- "serde",
- "toml 0.7.8",
-]
-
-[[package]]
-name = "alacritty_config_derive"
-version = "0.2.2-dev"
-source = "git+https://github.com/zed-industries/alacritty?rev=33306142195b354ef3485ca2b1d8a85dfc6605ca#33306142195b354ef3485ca2b1d8a85dfc6605ca"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.37",
-]
-
 [[package]]
 name = "alacritty_terminal"
-version = "0.20.0-dev"
-source = "git+https://github.com/zed-industries/alacritty?rev=33306142195b354ef3485ca2b1d8a85dfc6605ca#33306142195b354ef3485ca2b1d8a85dfc6605ca"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35229555d7cc7e83392dfc27c96bec560b1076d756184893296cd60125f4a264"
 dependencies = [
- "alacritty_config",
- "alacritty_config_derive",
- "base64 0.13.1",
+ "base64 0.21.4",
  "bitflags 2.4.1",
  "home",
  "libc",
  "log",
- "mio 0.6.23",
- "mio-anonymous-pipes",
- "mio-extras",
- "miow 0.3.7",
- "nix 0.26.4",
+ "miow 0.6.0",
  "parking_lot 0.12.1",
- "regex-automata 0.1.10",
+ "piper",
+ "polling 3.3.2",
+ "regex-automata 0.4.5",
+ "rustix-openpty",
  "serde",
- "serde_yaml",
  "signal-hook",
- "signal-hook-mio",
- "toml 0.7.8",
  "unicode-width",
  "vte",
  "windows-sys 0.48.0",
@@ -444,7 +419,7 @@ dependencies = [
  "futures-lite",
  "log",
  "parking",
- "polling",
+ "polling 2.8.0",
  "rustix 0.37.23",
  "slab",
  "socket2 0.4.9",
@@ -1155,7 +1130,7 @@ dependencies = [
  "serde_json",
  "syn 1.0.109",
  "tempfile",
- "toml 0.5.11",
+ "toml",
 ]
 
 [[package]]
@@ -1515,7 +1490,7 @@ dependencies = [
  "time",
  "tokio",
  "tokio-tungstenite",
- "toml 0.5.11",
+ "toml",
  "tonic",
  "tower",
  "tracing",
@@ -2018,6 +1993,12 @@ dependencies = [
  "windows-sys 0.48.0",
 ]
 
+[[package]]
+name = "cursor-icon"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991"
+
 [[package]]
 name = "dashmap"
 version = "5.5.3"
@@ -3611,7 +3592,7 @@ dependencies = [
  "log",
  "mime",
  "once_cell",
- "polling",
+ "polling 2.8.0",
  "slab",
  "sluice",
  "tracing",
@@ -3951,12 +3932,6 @@ dependencies = [
  "safemem",
 ]
 
-[[package]]
-name = "linked-hash-map"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
-
 [[package]]
 name = "linkme"
 version = "0.3.17"
@@ -4313,19 +4288,6 @@ dependencies = [
  "windows-sys 0.48.0",
 ]
 
-[[package]]
-name = "mio-anonymous-pipes"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6bc513025fe5005a3aa561b50fdb2cda5a150b84800ae02acd8aa9ed62ca1a6b"
-dependencies = [
- "mio 0.6.23",
- "miow 0.3.7",
- "parking_lot 0.11.2",
- "spsc-buffer",
- "winapi 0.3.9",
-]
-
 [[package]]
 name = "mio-extras"
 version = "2.0.6"
@@ -4338,17 +4300,6 @@ dependencies = [
  "slab",
 ]
 
-[[package]]
-name = "mio-uds"
-version = "0.6.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
-dependencies = [
- "iovec",
- "libc",
- "mio 0.6.23",
-]
-
 [[package]]
 name = "miow"
 version = "0.2.2"
@@ -4363,11 +4314,11 @@ dependencies = [
 
 [[package]]
 name = "miow"
-version = "0.3.7"
+version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
+checksum = "359f76430b20a79f9e20e115b3428614e654f04fab314482fc0fda0ebd3c6044"
 dependencies = [
- "winapi 0.3.9",
+ "windows-sys 0.48.0",
 ]
 
 [[package]]
@@ -4527,17 +4478,6 @@ dependencies = [
  "libc",
 ]
 
-[[package]]
-name = "nix"
-version = "0.26.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
-dependencies = [
- "bitflags 1.3.2",
- "cfg-if 1.0.0",
- "libc",
-]
-
 [[package]]
 name = "nix"
 version = "0.27.1"
@@ -5308,6 +5248,17 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
+[[package]]
+name = "piper"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4"
+dependencies = [
+ "atomic-waker",
+ "fastrand 2.0.0",
+ "futures-io",
+]
+
 [[package]]
 name = "pkcs1"
 version = "0.7.5"
@@ -5399,6 +5350,20 @@ dependencies = [
  "windows-sys 0.48.0",
 ]
 
+[[package]]
+name = "polling"
+version = "3.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "545c980a3880efd47b2e262f6a4bb6daad6555cf3367aa9c4e52895f69537a41"
+dependencies = [
+ "cfg-if 1.0.0",
+ "concurrent-queue",
+ "pin-project-lite 0.2.13",
+ "rustix 0.38.30",
+ "tracing",
+ "windows-sys 0.52.0",
+]
+
 [[package]]
 name = "pollster"
 version = "0.2.5"
@@ -5475,7 +5440,7 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
 dependencies = [
- "toml 0.5.11",
+ "toml",
 ]
 
 [[package]]
@@ -5582,7 +5547,7 @@ dependencies = [
  "terminal",
  "text",
  "thiserror",
- "toml 0.5.11",
+ "toml",
  "unindent",
  "util",
 ]
@@ -6025,6 +5990,17 @@ dependencies = [
  "regex-syntax 0.7.5",
 ]
 
+[[package]]
+name = "regex-automata"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax 0.8.2",
+]
+
 [[package]]
 name = "regex-syntax"
 version = "0.6.29"
@@ -6037,6 +6013,12 @@ version = "0.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
 
+[[package]]
+name = "regex-syntax"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
+
 [[package]]
 name = "rend"
 version = "0.4.0"
@@ -6405,11 +6387,23 @@ checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca"
 dependencies = [
  "bitflags 2.4.1",
  "errno",
+ "itoa",
  "libc",
  "linux-raw-sys 0.4.12",
  "windows-sys 0.52.0",
 ]
 
+[[package]]
+name = "rustix-openpty"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a25c3aad9fc1424eb82c88087789a7d938e1829724f3e4043163baf0d13cfc12"
+dependencies = [
+ "errno",
+ "libc",
+ "rustix 0.38.30",
+]
+
 [[package]]
 name = "rustls"
 version = "0.19.1"
@@ -6878,15 +6872,6 @@ dependencies = [
  "syn 2.0.37",
 ]
 
-[[package]]
-name = "serde_spanned"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
-dependencies = [
- "serde",
-]
-
 [[package]]
 name = "serde_urlencoded"
 version = "0.7.1"
@@ -6899,18 +6884,6 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "serde_yaml"
-version = "0.8.26"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b"
-dependencies = [
- "indexmap 1.9.3",
- "ryu",
- "serde",
- "yaml-rust",
-]
-
 [[package]]
 name = "settings"
 version = "0.1.0"
@@ -6932,7 +6905,7 @@ dependencies = [
  "serde_json",
  "serde_json_lenient",
  "smallvec",
- "toml 0.5.11",
+ "toml",
  "tree-sitter",
  "tree-sitter-json 0.19.0",
  "unindent",
@@ -7038,18 +7011,6 @@ dependencies = [
  "signal-hook-registry",
 ]
 
-[[package]]
-name = "signal-hook-mio"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
-dependencies = [
- "libc",
- "mio 0.6.23",
- "mio-uds",
- "signal-hook",
-]
-
 [[package]]
 name = "signal-hook-registry"
 version = "1.4.1"
@@ -7240,12 +7201,6 @@ dependencies = [
  "der",
 ]
 
-[[package]]
-name = "spsc-buffer"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be6c3f39c37a4283ee4b43d1311c828f2e1fb0541e76ea0cb1a2abd9ef2f5b3b"
-
 [[package]]
 name = "sqlez"
 version = "0.1.0"
@@ -7909,7 +7864,7 @@ dependencies = [
  "serde_json",
  "settings",
  "story",
- "toml 0.5.11",
+ "toml",
  "util",
  "uuid 1.4.1",
 ]
@@ -8214,26 +8169,11 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "toml"
-version = "0.7.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
-dependencies = [
- "serde",
- "serde_spanned",
- "toml_datetime",
- "toml_edit",
-]
-
 [[package]]
 name = "toml_datetime"
 version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
-dependencies = [
- "serde",
-]
 
 [[package]]
 name = "toml_edit"
@@ -8242,8 +8182,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
 dependencies = [
  "indexmap 2.0.0",
- "serde",
- "serde_spanned",
  "toml_datetime",
  "winnow",
 ]
@@ -9083,10 +9021,12 @@ dependencies = [
 
 [[package]]
 name = "vte"
-version = "0.11.1"
+version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197"
+checksum = "40eb22ae96f050e0c0d6f7ce43feeae26c348fc4dea56928ca81537cfaa6188b"
 dependencies = [
+ "bitflags 2.4.1",
+ "cursor-icon",
  "log",
  "serde",
  "utf8parse",
@@ -9660,15 +9600,6 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9"
 
-[[package]]
-name = "yaml-rust"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
-dependencies = [
- "linked-hash-map",
-]
-
 [[package]]
 name = "yansi"
 version = "0.5.1"
@@ -9777,7 +9708,7 @@ dependencies = [
  "theme_selector",
  "thiserror",
  "tiny_http",
- "toml 0.5.11",
+ "toml",
  "tree-sitter",
  "tree-sitter-bash",
  "tree-sitter-c",

crates/terminal/Cargo.toml 🔗

@@ -18,7 +18,7 @@ db = { path = "../db" }
 theme = { path = "../theme" }
 util = { path = "../util" }
 
-alacritty_terminal = { git = "https://github.com/zed-industries/alacritty", rev = "33306142195b354ef3485ca2b1d8a85dfc6605ca" }
+alacritty_terminal = "0.21"
 procinfo = { git = "https://github.com/zed-industries/wezterm", rev = "5cd757e5f2eb039ed0c6bb6512223e69d5efc64d", default-features = false }
 smallvec.workspace = true
 smol.workspace = true

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

@@ -1,5 +1,4 @@
-use alacritty_terminal::term::color::Rgb as AlacRgb;
-
+use alacritty_terminal::vte::ansi::Rgb as AlacRgb;
 use gpui::Rgba;
 
 //Convenience method to convert from a GPUI color to an alacritty Rgb
@@ -8,5 +7,5 @@ pub fn to_alac_rgb(color: impl Into<Rgba>) -> AlacRgb {
     let r = ((color.r * color.a) * 255.) as u8;
     let g = ((color.g * color.a) * 255.) as u8;
     let b = ((color.b * color.a) * 255.) as u8;
-    AlacRgb::new(r, g, b)
+    AlacRgb { r, g, b }
 }

crates/terminal/src/terminal.rs 🔗

@@ -3,8 +3,6 @@ pub use alacritty_terminal;
 pub mod terminal_settings;
 
 use alacritty_terminal::{
-    ansi::{ClearMode, Handler},
-    config::{Config, Program, PtyConfig, Scrolling},
     event::{Event as AlacTermEvent, EventListener, Notify, WindowSize},
     event_loop::{EventLoop, Msg, Notifier},
     grid::{Dimensions, Scroll as AlacScroll},
@@ -13,11 +11,11 @@ use alacritty_terminal::{
     sync::FairMutex,
     term::{
         cell::Cell,
-        color::Rgb,
         search::{Match, RegexIter, RegexSearch},
-        RenderableCursor, TermMode,
+        Config, RenderableCursor, TermMode,
     },
     tty::{self, setup_env},
+    vte::ansi::{ClearMode, Handler, NamedPrivateMode, PrivateMode, Rgb},
     Term,
 };
 use anyhow::{bail, Result};
@@ -58,7 +56,6 @@ use gpui::{
 };
 
 use crate::mappings::{colors::to_alac_rgb, keys::to_esc_str};
-use lazy_static::lazy_static;
 
 actions!(
     terminal,
@@ -75,15 +72,6 @@ const DEBUG_TERMINAL_HEIGHT: Pixels = px(30.);
 const DEBUG_CELL_WIDTH: Pixels = px(5.);
 const DEBUG_LINE_HEIGHT: Pixels = px(5.);
 
-lazy_static! {
-    // Regex Copied from alacritty's ui_config.rs and modified its declaration slightly:
-    // * avoid Rust-specific escaping.
-    // * use more strict regex for `file://` protocol matching: original regex has `file:` inside, but we want to avoid matching `some::file::module` strings.
-    static ref URL_REGEX: RegexSearch = RegexSearch::new(r#"(ipfs:|ipns:|magnet:|mailto:|gemini://|gopher://|https://|http://|news:|file://|git://|ssh:|ftp://)[^\u{0000}-\u{001F}\u{007F}-\u{009F}<>"\s{-}\^⟨⟩`]+"#).unwrap();
-
-    static ref WORD_REGEX: RegexSearch = RegexSearch::new(r#"[\w.\[\]:/@\-~]+"#).unwrap();
-}
-
 ///Upward flowing events, for changing the title and such
 #[derive(Clone, Debug)]
 pub enum Event {
@@ -289,66 +277,70 @@ impl TerminalBuilder {
     pub fn new(
         working_directory: Option<PathBuf>,
         shell: Shell,
-        mut env: HashMap<String, String>,
+        env: HashMap<String, String>,
         blink_settings: Option<TerminalBlink>,
         alternate_scroll: AlternateScroll,
         window: AnyWindowHandle,
     ) -> Result<TerminalBuilder> {
-        let pty_config = {
+        let pty_options = {
             let alac_shell = match shell.clone() {
                 Shell::System => None,
-                Shell::Program(program) => Some(Program::Just(program)),
-                Shell::WithArguments { program, args } => Some(Program::WithArgs { program, args }),
+                Shell::Program(program) => {
+                    Some(alacritty_terminal::tty::Shell::new(program, Vec::new()))
+                }
+                Shell::WithArguments { program, args } => {
+                    Some(alacritty_terminal::tty::Shell::new(program, args))
+                }
             };
 
-            PtyConfig {
+            alacritty_terminal::tty::Options {
                 shell: alac_shell,
                 working_directory: working_directory.clone(),
                 hold: false,
             }
         };
 
-        //TODO: Properly set the current locale,
-        env.insert("LC_ALL".to_string(), "en_US.UTF-8".to_string());
-        env.insert("ZED_TERM".to_string(), true.to_string());
+        // First, setup Alacritty's env
+        setup_env();
 
-        let alac_scrolling = Scrolling::default();
-        // alac_scrolling.set_history((BACK_BUFFER_SIZE * 2) as u32);
+        // Then setup configured environment variables
+        for (key, value) in env {
+            std::env::set_var(key, value);
+        }
+        //TODO: Properly set the current locale,
+        std::env::set_var("LC_ALL", "en_US.UTF-8");
+        std::env::set_var("ZED_TERM", "true");
 
         let config = Config {
-            pty_config: pty_config.clone(),
-            env,
-            scrolling: alac_scrolling,
+            scrolling_history: 10000,
             ..Default::default()
         };
 
-        setup_env(&config);
-
         //Spawn a task so the Alacritty EventLoop can communicate with us in a view context
         //TODO: Remove with a bounded sender which can be dispatched on &self
         let (events_tx, events_rx) = unbounded();
         //Set up the terminal...
         let mut term = Term::new(
-            &config,
+            config,
             &TerminalSize::default(),
             ZedListener(events_tx.clone()),
         );
 
         //Start off blinking if we need to
         if let Some(TerminalBlink::On) = blink_settings {
-            term.set_mode(alacritty_terminal::ansi::Mode::BlinkingCursor)
+            term.set_private_mode(PrivateMode::Named(NamedPrivateMode::BlinkingCursor));
         }
 
         //Alacritty defaults to alternate scrolling being on, so we just need to turn it off.
         if let AlternateScroll::Off = alternate_scroll {
-            term.unset_mode(alacritty_terminal::ansi::Mode::AlternateScroll)
+            term.unset_private_mode(PrivateMode::Named(NamedPrivateMode::AlternateScroll));
         }
 
         let term = Arc::new(FairMutex::new(term));
 
         //Setup the pty...
         let pty = match tty::new(
-            &pty_config,
+            &pty_options,
             TerminalSize::default().into(),
             window.window_id().as_u64(),
         ) {
@@ -370,13 +362,16 @@ impl TerminalBuilder {
             term.clone(),
             ZedListener(events_tx.clone()),
             pty,
-            pty_config.hold,
+            pty_options.hold,
             false,
         );
 
         //Kick things off
         let pty_tx = event_loop.channel();
-        let _io_thread = event_loop.spawn();
+        let _io_thread = event_loop.spawn(); // DANGER
+
+        let url_regex = RegexSearch::new(r#"(ipfs:|ipns:|magnet:|mailto:|gemini://|gopher://|https://|http://|news:|file://|git://|ssh:|ftp://)[^\u{0000}-\u{001F}\u{007F}-\u{009F}<>"\s{-}\^⟨⟩`]+"#).unwrap();
+        let word_regex = RegexSearch::new(r#"[\w.\[\]:/@\-~]+"#).unwrap();
 
         let terminal = Terminal {
             pty_tx: Notifier(pty_tx),
@@ -396,6 +391,8 @@ impl TerminalBuilder {
             selection_phase: SelectionPhase::Ended,
             cmd_pressed: false,
             hovered_word: false,
+            url_regex,
+            word_regex,
         };
 
         Ok(TerminalBuilder {
@@ -514,7 +511,7 @@ impl Default for TerminalContent {
             selection_text: Default::default(),
             selection: Default::default(),
             cursor: RenderableCursor {
-                shape: alacritty_terminal::ansi::CursorShape::Block,
+                shape: alacritty_terminal::vte::ansi::CursorShape::Block,
                 point: AlacPoint::new(Line(0), Column(0)),
             },
             cursor_char: Default::default(),
@@ -550,6 +547,8 @@ pub struct Terminal {
     selection_phase: SelectionPhase,
     cmd_pressed: bool,
     hovered_word: bool,
+    url_regex: RegexSearch,
+    word_regex: RegexSearch,
 }
 
 impl Terminal {
@@ -760,7 +759,7 @@ impl Terminal {
                     let url_match = min_index..=max_index;
 
                     Some((url, true, url_match))
-                } else if let Some(word_match) = regex_match_at(term, point, &WORD_REGEX) {
+                } else if let Some(word_match) = regex_match_at(term, point, &mut self.word_regex) {
                     let maybe_url_or_path =
                         term.bounds_to_string(*word_match.start(), *word_match.end());
                     let original_match = word_match.clone();
@@ -777,7 +776,7 @@ impl Terminal {
                             (word_match, maybe_url_or_path)
                         };
 
-                    let is_url = match regex_match_at(term, point, &URL_REGEX) {
+                    let is_url = match regex_match_at(term, point, &mut self.url_regex) {
                         Some(url_match) => {
                             // `]` is a valid symbol in the `file://` URL, so the regex match will include it
                             // consider that when ensuring that the URL match is the same as the original word
@@ -1275,14 +1274,14 @@ impl Terminal {
 
     pub fn find_matches(
         &mut self,
-        searcher: RegexSearch,
+        mut searcher: RegexSearch,
         cx: &mut ModelContext<Self>,
     ) -> Task<Vec<RangeInclusive<AlacPoint>>> {
         let term = self.term.clone();
         cx.background_executor().spawn(async move {
             let term = term.lock();
 
-            all_search_matches(&term, &searcher).collect()
+            all_search_matches(&term, &mut searcher).collect()
         })
     }
 
@@ -1332,7 +1331,7 @@ impl EventEmitter<Event> for Terminal {}
 
 /// Based on alacritty/src/display/hint.rs > regex_match_at
 /// Retrieve the match, if the specified point is inside the content matching the regex.
-fn regex_match_at<T>(term: &Term<T>, point: AlacPoint, regex: &RegexSearch) -> Option<Match> {
+fn regex_match_at<T>(term: &Term<T>, point: AlacPoint, regex: &mut RegexSearch) -> Option<Match> {
     visible_regex_match_iter(term, regex).find(|rm| rm.contains(&point))
 }
 
@@ -1340,7 +1339,7 @@ fn regex_match_at<T>(term: &Term<T>, point: AlacPoint, regex: &RegexSearch) -> O
 /// Iterate over all visible regex matches.
 pub fn visible_regex_match_iter<'a, T>(
     term: &'a Term<T>,
-    regex: &'a RegexSearch,
+    regex: &'a mut RegexSearch,
 ) -> impl Iterator<Item = Match> + 'a {
     let viewport_start = Line(-(term.grid().display_offset() as i32));
     let viewport_end = viewport_start + term.bottommost_line();
@@ -1362,7 +1361,7 @@ fn make_selection(range: &RangeInclusive<AlacPoint>) -> Selection {
 
 fn all_search_matches<'a, T>(
     term: &'a Term<T>,
-    regex: &'a RegexSearch,
+    regex: &'a mut RegexSearch,
 ) -> impl Iterator<Item = Match> + 'a {
     let start = AlacPoint::new(term.grid().topmost_line(), Column(0));
     let end = AlacPoint::new(term.grid().bottommost_line(), term.grid().last_column());

crates/terminal_view/src/terminal_element.rs 🔗

@@ -11,12 +11,11 @@ use itertools::Itertools;
 use language::CursorShape;
 use settings::Settings;
 use terminal::{
-    alacritty_terminal::ansi::NamedColor,
     alacritty_terminal::{
-        ansi::{Color as AnsiColor, Color::Named, CursorShape as AlacCursorShape},
         grid::Dimensions,
         index::Point as AlacPoint,
         term::{cell::Flags, TermMode},
+        vte::ansi::{Color as AnsiColor, Color::Named, CursorShape as AlacCursorShape, NamedColor},
     },
     terminal_settings::TerminalSettings,
     IndexedCell, Terminal, TerminalContent, TerminalSize,
@@ -308,7 +307,7 @@ impl TerminalElement {
     /// Converts the Alacritty cell styles to GPUI text styles and background color.
     fn cell_style(
         indexed: &IndexedCell,
-        fg: terminal::alacritty_terminal::ansi::Color,
+        fg: terminal::alacritty_terminal::vte::ansi::Color,
         // bg: terminal::alacritty_terminal::ansi::Color,
         colors: &Theme,
         text_style: &TextStyle,
@@ -998,11 +997,11 @@ fn to_highlighted_range_lines(
 }
 
 /// Converts a 2, 8, or 24 bit color ANSI color to the GPUI equivalent.
-fn convert_color(fg: &terminal::alacritty_terminal::ansi::Color, theme: &Theme) -> Hsla {
+fn convert_color(fg: &terminal::alacritty_terminal::vte::ansi::Color, theme: &Theme) -> Hsla {
     let colors = theme.colors();
     match fg {
         // Named and theme defined colors
-        terminal::alacritty_terminal::ansi::Color::Named(n) => match n {
+        terminal::alacritty_terminal::vte::ansi::Color::Named(n) => match n {
             NamedColor::Black => colors.terminal_ansi_black,
             NamedColor::Red => colors.terminal_ansi_red,
             NamedColor::Green => colors.terminal_ansi_green,
@@ -1034,11 +1033,11 @@ fn convert_color(fg: &terminal::alacritty_terminal::ansi::Color, theme: &Theme)
             NamedColor::DimForeground => colors.terminal_dim_foreground,
         },
         // 'True' colors
-        terminal::alacritty_terminal::ansi::Color::Spec(rgb) => {
+        terminal::alacritty_terminal::vte::ansi::Color::Spec(rgb) => {
             terminal::rgba_color(rgb.r, rgb.g, rgb.b)
         }
         // 8 bit, indexed colors
-        terminal::alacritty_terminal::ansi::Color::Indexed(i) => {
+        terminal::alacritty_terminal::vte::ansi::Color::Indexed(i) => {
             terminal::get_color_at_index(*i as usize, theme)
         }
     }