Atui.Key (Atui v0.1.0)

Copy Markdown View Source

Decodes a raw byte stream from the terminal into key events.

In raw mode the terminal hands us bytes, not keystrokes: arrows arrive as escape sequences, Ctrl-C as byte 3, and a non-ASCII character as two to four UTF-8 bytes. decode/1 turns whatever bytes have arrived so far into keys, returning any trailing incomplete sequence for the next read.

A lone ESC is indistinguishable from the start of an arrow key until either more bytes arrive or enough time passes — see flush/1.

Modifiers

A key held with Shift, Alt or Ctrl decodes as {modifiers, key}, the modifiers in a list: {[:shift], :left}, {[:ctrl], "a"}, {[:shift, :ctrl], :up}. Bare keys stay bare, so :left means exactly that.

Terminals report modified arrows as \e[1;2A and friends; the rxvt style (\e[a) is not decoded.

Summary

Functions

Decodes buffer into {keys, rest}.

Decodes a buffer that has stopped growing (an input timeout).

Types

modifier()

@type modifier() :: :shift | :alt | :ctrl

modifiers()

@type modifiers() :: [modifier()]

t()

@type t() ::
  :enter
  | :tab
  | :backspace
  | :esc
  | :up
  | :down
  | :left
  | :right
  | :home
  | :end
  | :delete
  | :page_up
  | :page_down
  | :ctrl_c
  | {:char, String.t()}
  | {modifiers(), t()}
  | {:unknown, binary()}

Functions

decode(buffer)

@spec decode(binary()) :: {[t()], binary()}

Decodes buffer into {keys, rest}.

rest is the tail of an escape or UTF-8 sequence that is not complete yet; prepend it to the next chunk of bytes.

flush(buffer)

@spec flush(binary()) :: [t()]

Decodes a buffer that has stopped growing (an input timeout).

This is where a pending ESC finally becomes the :esc key.