# `Drafter.Terminal.KittyKeyboard`
[🔗](https://github.com/jaman/drafter/blob/main/lib/drafter/terminal/kitty_keyboard.ex#L1)

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/0` yields `{: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 what `push/0` asked 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.

# `event`

```elixir
@type event() ::
  Drafter.Terminal.ANSI.event()
  | {:key_down, key(), Drafter.Terminal.ANSI.modifiers()}
  | {:key_up, key(), Drafter.Terminal.ANSI.modifiers()}
  | {:key_release_support, boolean()}
```

# `key`

```elixir
@type key() :: atom() | non_neg_integer()
```

# `key_down`

```elixir
@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`

```elixir
@spec parse(binary(), boolean()) :: {[event()], binary()} | :no_match
```

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`.

# `pop`

```elixir
@spec pop() :: String.t()
```

The sequence that turns it off again.

# `push`

```elixir
@spec push() :: String.t()
```

The sequence that turns the protocol on for the running program.

# `query`

```elixir
@spec query() :: String.t()
```

The sequence that asks the terminal whether it speaks the protocol.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
