From 2f8805ebed753846c9d68f7c631cd9901ef67a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tau=20G=C3=A4rtli?= Date: Wed, 11 Dec 2024 21:59:37 +0100 Subject: [PATCH] Prototype: Detect dark/light asynchronously --- Cargo.lock | 28 ++++++++++++++++++++++++++-- Cargo.toml | 4 ++++ helix-term/Cargo.toml | 1 + helix-term/src/application.rs | 10 ++++++++++ helix-term/src/ui/editor.rs | 1 + helix-tui/src/backend/crossterm.rs | 23 +++++++++++++++++++++++ helix-view/src/input.rs | 2 ++ 7 files changed, 67 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9cae3e3edaba..d9a20da95636 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,11 +239,11 @@ checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crossterm" version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +source = "git+https://github.com/bash/crossterm?branch=parse-osc#a9b1c10bfface5f7db53b41ae901c151fd25c6a9" dependencies = [ "bitflags", "crossterm_winapi", + "document-features", "filedescriptor", "futures-core", "libc", @@ -289,6 +289,15 @@ dependencies = [ "syn", ] +[[package]] +name = "document-features" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" +dependencies = [ + "litrs", +] + [[package]] name = "dunce" version = "1.0.5" @@ -1393,6 +1402,7 @@ dependencies = [ "signal-hook-tokio", "smallvec", "tempfile", + "terminal-colorsaurus", "termini", "thiserror 2.0.3", "tokio", @@ -1794,6 +1804,12 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + [[package]] name = "lock_api" version = "0.4.12" @@ -2378,6 +2394,14 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "terminal-colorsaurus" +version = "0.4.7" +source = "git+https://github.com/bash/terminal-colorsaurus?branch=parse-utils#317dcd9b09f4f55c4c664f0a7fe9557bf60792ae" +dependencies = [ + "cfg-if", +] + [[package]] name = "termini" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index 753be4b462c4..4a16f56e0c32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,3 +52,7 @@ repository = "https://github.com/helix-editor/helix" homepage = "https://helix-editor.com" license = "MPL-2.0" rust-version = "1.76" + +[patch.crates-io] +crossterm = { git = "https://github.com/bash/crossterm", branch = "parse-osc" } +terminal-colorsaurus = { git = "https://github.com/bash/terminal-colorsaurus", branch = "parse-utils" } diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index fb9d48babffe..f86f1e2ee4f3 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -43,6 +43,7 @@ tokio-stream = "0.1" futures-util = { version = "0.3", features = ["std", "async-await"], default-features = false } arc-swap = { version = "1.7.1" } termini = "1" +terminal-colorsaurus = { version = "0.4.7", default-features = false } # Logging fern = "0.7" diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index a567815fcaa6..c7e12a1629ff 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -642,6 +642,16 @@ impl Application { }; // Handle key events let should_redraw = match event.unwrap() { + CrosstermEvent::OscString(osc_string) => { + if let Some(color_string) = osc_string.strip_prefix(b"11;") { + if let Some(color) = terminal_colorsaurus::parse::xparsecolor(color_string) { + let is_light = color.perceived_lightness() >= 50; + self.editor.set_status(format!("is_light = {}", is_light)) + } + } + + true + } CrosstermEvent::Resize(width, height) => { self.terminal .resize(Rect::new(0, 0, width, height)) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 5179be4f4e1c..3008825eca53 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -1332,6 +1332,7 @@ impl Component for EditorView { }; match event { + Event::Noop => EventResult::Consumed(None), Event::Paste(contents) => { self.handle_non_key_input(&mut cx); cx.count = cx.editor.count; diff --git a/helix-tui/src/backend/crossterm.rs b/helix-tui/src/backend/crossterm.rs index e8947ee0861f..b5653977a8b3 100644 --- a/helix-tui/src/backend/crossterm.rs +++ b/helix-tui/src/backend/crossterm.rs @@ -185,6 +185,7 @@ where ) )?; } + execute!(self.buffer, QueryBackgroundColor)?; Ok(()) } @@ -462,3 +463,25 @@ impl Command for SetUnderlineColor { )) } } + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct QueryBackgroundColor; + +impl crossterm::Command for QueryBackgroundColor { + fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result { + f.write_str("\x1b]11;?\x07") + } + + #[cfg(windows)] + fn execute_winapi(&self) -> std::io::Result<()> { + Err(std::io::Error::new( + std::io::ErrorKind::Other, + "QueryBackgroundColor not supported by winapi.", + )) + } + + #[cfg(windows)] + fn is_ansi_code_supported(&self) -> bool { + true + } +} diff --git a/helix-view/src/input.rs b/helix-view/src/input.rs index 5f5067eac9f8..e28564550376 100644 --- a/helix-view/src/input.rs +++ b/helix-view/src/input.rs @@ -15,6 +15,7 @@ pub enum Event { Paste(String), Resize(u16, u16), IdleTimeout, + Noop, } #[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)] @@ -441,6 +442,7 @@ impl From for Event { crossterm::event::Event::FocusGained => Self::FocusGained, crossterm::event::Event::FocusLost => Self::FocusLost, crossterm::event::Event::Paste(s) => Self::Paste(s), + crossterm::event::Event::OscString(_s) => Self::Noop, } } }