Unnamed repository; edit this file 'description' to name the repository.
tui: Cache the keyboard enhancement check
Wether the host terminal supports keyboard enhancement can be cached
for the lifetime of a Helix session.
Caching this lookup prevents a potential lockup within crossterm's
event reading system where the query for the keyboard enhancement
support waits on the next keyboard event, which can happen if the
crossterm event stream is checked by `tokio::select!` in another
thread.
| -rw-r--r-- | Cargo.lock | 1 | ||||
| -rw-r--r-- | helix-tui/Cargo.toml | 1 | ||||
| -rw-r--r-- | helix-tui/src/backend/crossterm.rs | 14 |
3 files changed, 14 insertions, 2 deletions
diff --git a/Cargo.lock b/Cargo.lock index 231273956..a03f9c921 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1202,6 +1202,7 @@ dependencies = [ "helix-core", "helix-view", "log", + "once_cell", "serde", "termini", "unicode-segmentation", diff --git a/helix-tui/Cargo.toml b/helix-tui/Cargo.toml index 3ca7e044e..8a6d5367d 100644 --- a/helix-tui/Cargo.toml +++ b/helix-tui/Cargo.toml @@ -22,6 +22,7 @@ unicode-segmentation = "1.10" crossterm = { version = "0.26", optional = true } termini = "0.1" serde = { version = "1", "optional" = true, features = ["derive"]} +once_cell = "1.17" log = "~0.4" helix-view = { version = "0.6", path = "../helix-view", features = ["term"] } helix-core = { version = "0.6", path = "../helix-core" } diff --git a/helix-tui/src/backend/crossterm.rs b/helix-tui/src/backend/crossterm.rs index e81c1e008..7c512ce3e 100644 --- a/helix-tui/src/backend/crossterm.rs +++ b/helix-tui/src/backend/crossterm.rs @@ -15,6 +15,7 @@ use crossterm::{ Command, }; use helix_view::graphics::{Color, CursorKind, Modifier, Rect, UnderlineStyle}; +use once_cell::sync::OnceCell; use std::{ fmt, io::{self, Write}, @@ -57,6 +58,7 @@ impl Capabilities { pub struct CrosstermBackend<W: Write> { buffer: W, capabilities: Capabilities, + supports_keyboard_enhancement_protocol: OnceCell<bool>, } impl<W> CrosstermBackend<W> @@ -67,8 +69,16 @@ where CrosstermBackend { buffer, capabilities: Capabilities::from_env_or_default(), + supports_keyboard_enhancement_protocol: OnceCell::new(), } } + + #[inline] + fn supports_keyboard_enhancement_protocol(&self) -> io::Result<bool> { + self.supports_keyboard_enhancement_protocol + .get_or_try_init(terminal::supports_keyboard_enhancement) + .copied() + } } impl<W> Write for CrosstermBackend<W> @@ -100,7 +110,7 @@ where if config.enable_mouse_capture { execute!(self.buffer, EnableMouseCapture)?; } - if matches!(terminal::supports_keyboard_enhancement(), Ok(true)) { + if self.supports_keyboard_enhancement_protocol()? { log::debug!("The enhanced keyboard protocol is supported on this terminal"); execute!( self.buffer, @@ -121,7 +131,7 @@ where if config.enable_mouse_capture { execute!(self.buffer, DisableMouseCapture)?; } - if matches!(terminal::supports_keyboard_enhancement(), Ok(true)) { + if self.supports_keyboard_enhancement_protocol()? { execute!(self.buffer, PopKeyboardEnhancementFlags)?; } execute!( |