on master help sign in
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.

commit611701c36290b81c3c51ed30c49245f341a580e8 authorMichael Davis <mcarsondavis@gmail.com> dateSun 5 Mar 2023, 12:13 (4 years ago) parent3d85024
3 files changed+14−2
Cargo.lock+1 helix-tui/Cargo.toml+1 helix-tui/src/backend/crossterm.rs+12−2
Cargo.lock+1
@@ -1202,6 +1202,7 @@ dependencies = [
12021202 "helix-core",
12031203 "helix-view",
12041204 "log",
1205+ "once_cell",
12051206 "serde",
12061207 "termini",
12071208 "unicode-segmentation",
helix-tui/Cargo.toml+1
@@ -22,6 +22,7 @@ unicode-segmentation = "1.10"
2222crossterm = { version = "0.26", optional = true }
2323termini = "0.1"
2424serde = { version = "1", "optional" = true, features = ["derive"]}
25+once_cell = "1.17"
2526log = "~0.4"
2627helix-view = { version = "0.6", path = "../helix-view", features = ["term"] }
2728helix-core = { version = "0.6", path = "../helix-core" }
helix-tui/src/backend/crossterm.rs+12−2
@@ -15,6 +15,7 @@ use crossterm::{
1515 Command,
1616};
1717use helix_view::graphics::{Color, CursorKind, Modifier, Rect, UnderlineStyle};
18+use once_cell::sync::OnceCell;
1819use std::{
1920 fmt,
2021 io::{self, Write},
@@ -57,6 +58,7 @@ impl Capabilities {
5758pub struct CrosstermBackend<W: Write> {
5859 buffer: W,
5960 capabilities: Capabilities,
61+ supports_keyboard_enhancement_protocol: OnceCell<bool>,
6062}
6163
6264impl<W> CrosstermBackend<W>
@@ -67,8 +69,16 @@ where
6769 CrosstermBackend {
6870 buffer,
6971 capabilities: Capabilities::from_env_or_default(),
72+ supports_keyboard_enhancement_protocol: OnceCell::new(),
7073 }
7174 }
75+
76+ #[inline]
77+ fn supports_keyboard_enhancement_protocol(&self) -> io::Result<bool> {
78+ self.supports_keyboard_enhancement_protocol
79+ .get_or_try_init(terminal::supports_keyboard_enhancement)
80+ .copied()
81+ }
7282}
7383
7484impl<W> Write for CrosstermBackend<W>
@@ -100,7 +110,7 @@ where
100110 if config.enable_mouse_capture {
101111 execute!(self.buffer, EnableMouseCapture)?;
102112 }
103− if matches!(terminal::supports_keyboard_enhancement(), Ok(true)) {
113+ if self.supports_keyboard_enhancement_protocol()? {
104114 log::debug!("The enhanced keyboard protocol is supported on this terminal");
105115 execute!(
106116 self.buffer,
@@ -121,7 +131,7 @@ where
121131 if config.enable_mouse_capture {
122132 execute!(self.buffer, DisableMouseCapture)?;
123133 }
124− if matches!(terminal::supports_keyboard_enhancement(), Ok(true)) {
134+ if self.supports_keyboard_enhancement_protocol()? {
125135 execute!(self.buffer, PopKeyboardEnhancementFlags)?;
126136 }
127137 execute!(