Skip to content

Commit 3ee3a11

Browse files
committed
fix(header): bound tty color query wall-clock wait
1 parent 95d7170 commit 3ee3a11

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

crates/vite_shared/src/header.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,9 @@ fn is_osc_query_unsupported() -> bool {
253253
#[cfg(unix)]
254254
const DA1: &str = "\x1b[c";
255255

256+
#[cfg(unix)]
257+
const QUERY_TERMINAL_COLORS_WALL_CLOCK_TIMEOUT_MS: u64 = 250;
258+
256259
/// Reads from a `BufRead` until one of two delimiter bytes is found.
257260
/// Modelled after `terminal-colorsaurus`'s `read_until2`.
258261
#[cfg(unix)]
@@ -294,6 +297,29 @@ fn read_until_either(
294297
/// ordering/completeness ambiguities of flat-buffer pattern matching.
295298
#[cfg(unix)]
296299
fn query_terminal_colors(palette_indices: &[u8]) -> (Option<Rgb>, Vec<(u8, Rgb)>) {
300+
let indices = palette_indices.to_vec();
301+
let (tx, rx) = std::sync::mpsc::channel();
302+
303+
let Ok(_handle) =
304+
std::thread::Builder::new().name("vp-tty-color-query".into()).spawn(move || {
305+
let _ = tx.send(query_terminal_colors_inner(&indices));
306+
})
307+
else {
308+
return (None, vec![]);
309+
};
310+
311+
rx.recv_timeout(Duration::from_millis(QUERY_TERMINAL_COLORS_WALL_CLOCK_TIMEOUT_MS))
312+
.unwrap_or((None, vec![]))
313+
}
314+
315+
/// Queries terminal colors using the DA1 sandwich technique with
316+
/// stream-based response parsing (modelled after `terminal-colorsaurus`).
317+
///
318+
/// Responses are read sequentially using `BufReader` + `read_until`,
319+
/// which provides exact response boundaries and eliminates the
320+
/// ordering/completeness ambiguities of flat-buffer pattern matching.
321+
#[cfg(unix)]
322+
fn query_terminal_colors_inner(palette_indices: &[u8]) -> (Option<Rgb>, Vec<(u8, Rgb)>) {
297323
use std::{
298324
fs::OpenOptions,
299325
io::{self, BufRead, BufReader},

0 commit comments

Comments
 (0)