The kitty keyboard protocol: the sequences that switch it on and off, and the parsing of the key reports a terminal sends while it is on.
push/0 asks for disambiguated escape codes, press/repeat/release event types,
every key as an escape code, and the text a key produces. pop/0 restores the
mode that was in force before. query/0 asks for the current flags; a terminal
that speaks the protocol answers CSI ? flags u, one that does not stays silent.
parse/1 turns one report into events for Drafter.Terminal.ANSI:
- a press yields the same
{:key, ...}or{:char, ...}event the legacy encoding would have produced, followed by{:key_down, key, modifiers} - a repeat yields the legacy event only
- a release yields
{:key_up, key, modifiers} - the reply to
query/0yields{:key_release_support, true}when the flags in force include event types, so releases will be reported, and{:key_release_support, false}when they do not — a terminal that speaks the protocol but took only some of whatpush/0asked for
key in :key_down and :key_up is the unshifted key: :a for both a and
A, :"1" for both 1 and !, a name such as :left_shift or :kp_5 for a key
with no glyph, and an integer codepoint for a glyph outside ASCII. modifiers
is the [:ctrl, :alt, :shift] subset held, in that order, and may be empty.
Caps lock and num lock are not modifiers. Keys with no glyph produce no legacy
event unless the terminal reported text for them.
Summary
Functions
The {:key_down, key, modifiers} event matching a legacy key press.
Parse one report at the head of buffer.
The sequence that turns it off again.
The sequence that turns the protocol on for the running program.
The sequence that asks the terminal whether it speaks the protocol.
Types
@type event() :: Drafter.Terminal.ANSI.event() | {:key_down, key(), Drafter.Terminal.ANSI.modifiers()} | {:key_up, key(), Drafter.Terminal.ANSI.modifiers()} | {:key_release_support, boolean()}
@type key() :: atom() | non_neg_integer()
Functions
@spec key_down({:key, atom()} | {:key, atom(), Drafter.Terminal.ANSI.modifiers()}) :: {:key_down, key(), Drafter.Terminal.ANSI.modifiers()}
The {:key_down, key, modifiers} event matching a legacy key press.
Used while the protocol is on for the keys a terminal still reports in their
legacy encoding, so every press has a :key_down whichever encoding it arrived in.
Parse one report at the head of buffer.
Returns the events it produced and the bytes after it, or :no_match when the
buffer does not begin with a report this module reads. A report whose final
byte has not arrived is :no_match as well; Drafter.Terminal.ANSI holds those
back before asking.
With key_release false, only reports the legacy encodings cannot produce are
read: a u final, or an event type or alternate key after a colon. With it true
every CSI key report is read, including the legacy forms, each press gaining its
:key_down.
@spec pop() :: String.t()
The sequence that turns it off again.
@spec push() :: String.t()
The sequence that turns the protocol on for the running program.
@spec query() :: String.t()
The sequence that asks the terminal whether it speaks the protocol.