Asks the connected terminal which graphics protocol it supports.
The terminal is asked rather than guessed at from environment variables, so the answer describes the terminal a session is actually attached to. That matters for a session served over ssh or telnet, where the host's own environment says nothing about the client, and locally under a multiplexer, which strips the variables a guess would rely on.
run/3 performs the whole exchange: it writes FrenchCurve.Capability.probe/0,
reads until the device attributes reply arrives or the deadline passes, and
returns the protocol together with any bytes that were not part of the answer.
{protocol, leftover} = Drafter.Terminal.Probe.run(write, read)The two functions are how transports differ. write takes iodata and puts it on
the wire. read takes a millisecond timeout and returns {:ok, bytes},
:timeout when nothing arrived in time, or {:error, reason}. A read must
wait up to the timeout it is given before reporting :timeout, because one
silent slice ends the exchange: a terminal that understands the queries answers
them at once.
Run it before the input pipeline starts. The replies are control sequences that
would otherwise be delivered as keystrokes, so they are consumed here; anything
the user typed during the exchange comes back as leftover and belongs to the
input pipeline.
Summary
Functions
The bytes to write to ask the terminal what it supports.
Turn collected replies into {protocol, leftover}.
Ask the terminal, and return {protocol, leftover}.
Whether replies holds the whole answer, so there is no point reading further.
Types
@type protocol() :: :kitty | :iterm2 | :sixel | nil
@type read_fun() :: (non_neg_integer() -> {:ok, binary()} | :timeout | {:error, term()})
Functions
@spec query() :: binary()
The bytes to write to ask the terminal what it supports.
For a transport that cannot read synchronously: write this, accumulate whatever
arrives, and use settled?/1 and resolve/1 on the accumulated bytes.
Turn collected replies into {protocol, leftover}.
leftover is replies with the answers removed — bytes that arrived during the
exchange without being part of it, which belong to the input pipeline.
Ask the terminal, and return {protocol, leftover}.
protocol is :kitty, :iterm2, :sixel, or nil when the terminal named
nothing usable or did not answer at all. leftover is the bytes that arrived
during the exchange without being part of it.
Options
:timeout- milliseconds to wait for the answer in total. Default200. A terminal that supports the queries answers immediately; the deadline only bounds one that ignores them.
Whether replies holds the whole answer, so there is no point reading further.
A transport collecting asynchronously must still give up on a deadline: a terminal that understands neither query never answers, and this never becomes true for it.