@@ -253,6 +253,9 @@ fn is_osc_query_unsupported() -> bool {
253253#[ cfg( unix) ]
254254const 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) ]
296299fn 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