Skip to content

std/keys ​

Decode raw terminal input bytes into key events. Everything that is not a plain character arrives as an escape sequence (arrows, function keys, Home/End, every modifier combination), and this module turns those bytes into a Key. It is pure byte logic with no syscalls, so read the bytes however you like, for example with std/term's raw mode, and feed them in.

milo
from "std/keys" import { Key, KeyCode, decodeKey }

Example ​

milo
let k = decodeKey("\x1b[A", 0)
match k.code {
    KeyCode.Up => print("up"),
    _ => print("other"),
}
print(k.size)   // 3

API reference ​

Key ​

milo
pub struct Key

A decoded key plus the number of input bytes it consumed.

size is 0 only for None (empty input) and Partial (incomplete sequence); in both cases the caller must not advance, or it would drop the prefix of a sequence still being received.

Fields: code: KeyCode, ctrl: bool, alt: bool, shift: bool, size: i64.

KeyCode ​

milo
pub enum KeyCode

Which key was pressed. Char carries a Unicode codepoint rather than a string so decoding never allocates.

Variants:

  • None
  • Unknown
  • Partial
  • Char(i32)
  • Enter
  • Tab
  • Escape
  • Backspace
  • Delete
  • Insert
  • Up
  • Down
  • Left
  • Right
  • Home
  • End
  • PageUp
  • PageDown
  • F(i32)
  • PasteStart
  • PasteEnd

Functions ​

applyModifier ​

milo
pub fn applyModifier(k: Key, mod: i64): Key

xterm encodes modifiers as a parameter of 1 + a bitmask, so ESC [ 1;5 A is ctrl+Up. Applies to both CSI and SS3 forms.

controlKey ​

milo
pub fn controlKey(b: i64): Key

Control bytes below 0x20 double as ctrl+letter. Tab, Enter and Escape have their own identities and are matched before falling through to ctrl+letter, because a user pressing Tab did not press ctrl+I even though the byte is the same.

decodeCsi ​

milo
pub fn decodeCsi(s: &string, start: i64, at: i64): Key

Decode a CSI sequence: the caller has already matched ESC [, and at points just past it.

decodeKey ​

milo
pub fn decodeKey(s: &string, at: i64): Key

Decode one key starting at byte offset at.

Returns None with size 0 on empty input, and Partial with size 0 when the bytes end mid-escape-sequence — the caller should keep the tail and retry after reading more.

decodeKeyFinal ​

milo
pub fn decodeKeyFinal(s: &string, at: i64): Key

Treat a buffer known to be complete as a finished key: resolves the lone-ESC ambiguity in favour of the Escape key. Use this after an input read has timed out with no further bytes.

letterKey ​

milo
pub fn letterKey(b: i64): KeyCode

Final letter of a CSI/SS3 sequence to its key.

plainKey ​

milo
pub fn plainKey(code: KeyCode, size: i64): Key

tildeKey ​

milo
pub fn tildeKey(n: i64): KeyCode

Map the numeric parameter of a ESC [ N ~ sequence to its key.