diff --git a/crates/vite_shared/src/header.rs b/crates/vite_shared/src/header.rs index c6bf7c70e6..1793b3acee 100644 --- a/crates/vite_shared/src/header.rs +++ b/crates/vite_shared/src/header.rs @@ -240,7 +240,6 @@ fn is_osc_query_unsupported() -> bool { if std::env::var_os("TMUX").is_some() || std::env::var_os("STY").is_some() { return true; } - false }) } @@ -254,6 +253,9 @@ fn is_osc_query_unsupported() -> bool { #[cfg(unix)] const DA1: &str = "\x1b[c"; +#[cfg(unix)] +const QUERY_TERMINAL_COLORS_WALL_CLOCK_TIMEOUT_MS: u64 = 250; + /// Reads from a `BufRead` until one of two delimiter bytes is found. /// Modelled after `terminal-colorsaurus`'s `read_until2`. #[cfg(unix)] @@ -295,6 +297,29 @@ fn read_until_either( /// ordering/completeness ambiguities of flat-buffer pattern matching. #[cfg(unix)] fn query_terminal_colors(palette_indices: &[u8]) -> (Option, Vec<(u8, Rgb)>) { + let indices = palette_indices.to_vec(); + let (tx, rx) = std::sync::mpsc::channel(); + + let Ok(_handle) = + std::thread::Builder::new().name("vp-tty-color-query".into()).spawn(move || { + let _ = tx.send(query_terminal_colors_inner(&indices)); + }) + else { + return (None, vec![]); + }; + + rx.recv_timeout(Duration::from_millis(QUERY_TERMINAL_COLORS_WALL_CLOCK_TIMEOUT_MS)) + .unwrap_or((None, vec![])) +} + +/// Queries terminal colors using the DA1 sandwich technique with +/// stream-based response parsing (modelled after `terminal-colorsaurus`). +/// +/// Responses are read sequentially using `BufReader` + `read_until`, +/// which provides exact response boundaries and eliminates the +/// ordering/completeness ambiguities of flat-buffer pattern matching. +#[cfg(unix)] +fn query_terminal_colors_inner(palette_indices: &[u8]) -> (Option, Vec<(u8, Rgb)>) { use std::{ fs::OpenOptions, io::{self, BufRead, BufReader}, @@ -536,6 +561,21 @@ pub fn vite_plus_header() -> String { render_header_variant(header_colors.blue, &header_colors.suffix_gradient, true, true) } +#[must_use] +pub fn vite_plus_header_static() -> String { + if !should_colorize() || !supports_true_color() { + return format!("VITE+{HEADER_SUFFIX}"); + } + + let suffix_gradient = gradient_eased( + HEADER_SUFFIX.chars().count(), + DEFAULT_BLUE, + DEFAULT_MAGENTA, + HEADER_SUFFIX_FADE_GAMMA, + ); + render_header_variant(DEFAULT_BLUE, &suffix_gradient, true, true) +} + #[cfg(all(test, unix))] mod tests { use std::io::{BufReader, Cursor};