class

TermBuf::Prober

Inherits Reference < Object

Stability: internal

Asks the terminal what it can do, rather than guessing from its name.

Every query goes out in one batch, and the last of them is a cursor position report. Every terminal answers that one, so its reply is the signal that everything else which was going to answer already has. The common case therefore costs one round trip rather than the full timeout, and the timeout is only a backstop for a terminal that answers nothing.

Bytes arriving during the probe window that are not replies are keystrokes. They are handed back rather than dropped, so a key pressed while the application was starting still reaches it.

Constants

CURSOR_POSITION = /\A\e\[(\d+);(\d+)R\z/
CURSOR_STYLE_QUERY = "\eP$q q\e\\"

DECRQSS for the cursor style: DCS $ q SP q ST asks the terminal to report the DECSCUSR setting it is currently in.

An experiment, and the only query there is for Capability::CursorShape — nothing else this shard can ask answers whether DECSCUSR does anything. A terminal that implements DECRQSS answers DCS 1 $ r Ps SP q ST with the shape it is set to, which is evidence it knows the setting exists; DCS 0 $ r ST is a terminal that understands the request and refuses this particular one, which is evidence it does not. Terminal.app and kitty answer neither, and silence changes nothing: the terminal's name is still the best that can be done for them.

CURSOR_STYLE_REPORT = /\A\eP([01])\$r(\d* q)?\e\\\z/

DCS Ps $ r ... ST, the DECRPSS reply, where a leading 1 means the request was valid and 0 that it was not. The payload of a valid one is the setting itself, Ps SP q for a cursor style, and it is matched rather than read: the shape the terminal happens to be in says nothing about whether it will take a new one.

DEFAULT_TIMEOUT = 250.milliseconds

Long enough for a terminal on the far end of a slow link, short enough not to be noticed when nothing answers.

KITTY_GRAPHICS_QUERY = "\e_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\e\\"

A one pixel RGB image, asked about rather than displayed.

KITTY_KEYBOARD = /\A\e\[\?\d*u\z/
MODE_CAPABILITIES = {2026 => Capability::SynchronizedOutput, 2027 => Capability::GraphemeClusters, 1004 => Capability::FocusEvents, 1006 => Capability::MouseSgr, 2004 => Capability::BracketedPaste}

The DEC private modes worth asking about, and the capability each one stands for. CSI ? Pm $ p is DECRQM and the reply is DECRPM, which is the only mechanism a terminal offers for saying it does not have something; every other query in the batch is silent about what it lacks.

Mode 2027 is asked about and never turned on. Enabling it changes how the terminal counts grapheme clusters, and the width probe measures this terminal with the mode off; switching it on afterwards would invalidate every width already established. See Capability::GraphemeClusters.

MODE_QUERIES = {2026 => :synchronized_output, 2027 => :grapheme_clusters, 1004 => :focus_events, 1006 => :mouse_sgr, 2004 => :bracketed_paste}

Which query a mode report answered, for Result#answered. A separate table because a symbol cannot be built out of a value at runtime.

MODE_REPORT = /\A\e\[\?(\d+);(\d+)\$y\z/
PRIMARY_ATTRIBUTES = /\A\e\[\?[\d;]*c\z/
QUERIES = String.build do |io| io << "\e[c" io << "\e[>c" io << "\e[>0q" io << TCAP_QUERY MODE_CAPABILITIES.each_key do |mode| ((io << "\e[?") << mode) << "$p" end io << "\e[?u" io << CURSOR_STYLE_QUERY io << KITTY_GRAPHICS_QUERY io << "\e[6n" end
TCAP_QUERY = "\eP+q5463;524742\e\\"

Tc and RGB are the terminfo capabilities that mean 24 bit colour; asking for them by hex name is how XTGETTCAP works.

TERMINAL_NAME = /\A\eP>\|(.*)\e\\\z/m

Constructors

new(input : IO, output : IO, timeout : Time::Span = DEFAULT_TIMEOUT)
Source

Instance methods

probe(base : Capabilities, distrusted : Capability = Capability::None) : Result

Sends the queries and folds whatever comes back into base.

A mode report for a capability in distrusted is recorded as answered and adds nothing: it is the answer of something in the middle rather than of the terminal at the end. A refusal is trusted whatever is in distrusted, since nothing forwards a mode it does not know. See EnvironmentDetector.distrusted.

Source
probe_temp_file

Asks whether the terminal will read image data out of a file rather than take it inline. Only worth asking once the graphics protocol is known to be there, and it needs somewhere to write, so it is separate from the main batch.

Source
timeout

How long to wait for the sentinel before giving up on the batch.

Source

Nested types