module
Tput::Probe
Overview
Runtime terminal probing.
Unlike Features/Emulator, which infer capabilities statically from
ENV and terminfo, this module discovers them by writing a batch of query
escape sequences to the terminal and reading the replies back (the same
technique used by Microsoft's edit):
- OSC 10 / OSC 11 -> default foreground / background color
- OSC 4 ; 0..15 -> the 16 indexed palette colors
- SGR 48;2 + DECRQSS -> whether 24-bit ("true") color survives a round trip: we set a distinctive RGB background, ask the terminal to report its current SGR, and check the reply still carries the RGB triplet.
- DECRQSS
q-> whether the terminal honors DECSCUSR cursor-style setting: we ask it to report its current cursor style; a valid1$r…<space>qreply confirms the hardware cursor is styleable. - OSC 12 ; ? -> whether the terminal can report (and thus set) its hardware cursor color.
- print
…+ DSR/CPR -> measured width of an ambiguous-width char - DA1 (
CSI c) -> device attributes, and a universal terminator: every terminal answers DA1, but not all answer the OSC queries, so its reply tells us when to stop reading.
Results are stored on Tput#features (Features#default_foreground,
#default_background, #palette, #ambiguous_width, #da_params).
Included Modules
- Crystallabs::Helpers::Logging
Direct including types
Defined in:
tput/probe.crConstant Summary
-
Log =
::Log.for((self.name.gsub("::", '.')).underscore)
Instance Method Summary
-
#build_probe_cleanup : String
Builds the post-probe cleanup string, run after all replies are consumed.
-
#build_probe_query : String
Builds the single batched query string.
-
#probe!(timeout : Time::Span = 3.seconds) : Bool
Probes the terminal for its features by round-tripping query sequences.
-
#probe_capable? : Bool
Whether probing is possible (both ends must be a real terminal).
-
#probe_consume(io : IO, timeout : Time::Span) : ProbeResult
Reads and parses the terminal's replies from io until DA1 arrives or a read times out.
Instance Method Detail
Builds the post-probe cleanup string, run after all replies are consumed.
The width probe printed … at column 1 (#build_probe_query does \r…),
so the leftover sits left of wherever the cursor was when probing started.
A bare \e8\e[J erases only from the saved column rightward, leaving
the … (and any echoed fragments) on screen when probing didn't begin at
column 1.
So: \e8 restores to the DECSC-saved cursor line (even if echoed output
wrapped it downward); \r parks at column 1 of that line; \e[J erases
to the end of the display, wiping the … and any echoed fragments
(including ones wrapped onto following lines); a final \e8 restores the
exact pre-probe cursor position.
Builds the single batched query string. DECSC (\e7) saves the cursor
up front so #probe! can restore it exactly and erase anything a
non-conforming terminal echoed back. For the width probe, \r parks the
cursor at column 1 so the CPR column maps directly to rendered width.
DA1 goes last so its reply terminates the read.
Probes the terminal for its features by round-tripping query sequences.
Returns true if at least the DA1 terminator came back (i.e. the
terminal participated), false if probing was skipped or timed out
with no response. timeout bounds the wait for each individual reply;
a responsive terminal returns almost immediately thanks to the DA1
sentinel.
Reads and parses the terminal's replies from io until DA1 arrives or a
read times out. OSC color replies are applied to features as they come
in; the ambiguous-width measurement and DA1 presence are returned.
Decoupled from @input so it can be exercised against an IO::Memory
holding canned responses, without a real terminal.