beer-protocols: format docs

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I8870fc54503c7ec033152e23b50df3ff6a6a6964
This commit is contained in:
raf 2026-06-26 17:16:45 +03:00
commit ea3867e8d0
No known key found for this signature in database
GPG key ID: 29D95B64378DB4BF

View file

@ -2,81 +2,94 @@
The terminal-protocol building blocks beer is built on: byte codecs, the The terminal-protocol building blocks beer is built on: byte codecs, the
terminfo capability table, character-set translation, SGR parsing, and the terminfo capability table, character-set translation, SGR parsing, and the
keyboard/mouse wire encoders. Everything here is a pure function or a plain keyboard/mouse wire encoders. Everything here is a pure function or a plain data
data type, with no terminal state, so each protocol detail can be read and type, with no terminal state, so each protocol detail can be read and tested on
tested on its own. beer feeds these into its `vte`-driven dispatcher and its its own. beer feeds these into its `vte`-driven dispatcher and its grid model.
grid model.
This README doubles as the reference for **which escape sequences, OSC This README doubles as the reference for **which escape sequences, OSC commands,
commands, and POSIX behaviours beer actually implements** - the parts a user and POSIX behaviours beer actually implements** - the parts a user notices.
notices. Sequences not listed here are parsed and ignored rather than passed Sequences not listed here are parsed and ignored rather than passed through.
through. Notation: `ESC` is `0x1b`, `CSI` is `ESC [`, `OSC` is `ESC ]`, `DCS` Notation: `ESC` is `0x1b`, `CSI` is `ESC [`, `OSC` is `ESC ]`, `DCS` is `ESC P`,
is `ESC P`, `ST` is the string terminator `ESC \` (a `BEL` is also accepted to `ST` is the string terminator `ESC \` (a `BEL` is also accepted to end an OSC).
end an OSC). `Ps` is a numeric parameter, `Pt` a text parameter. `Ps` is a numeric parameter, `Pt` a text parameter.
## Crate layout ## Crate layout
| Module | What it covers | <!--markdownlint-disable MD013-->
| --- | --- |
| `codec` | base64 (OSC 52), hex (XTGETTCAP names), `file://` URI percent-decoding (OSC 7) |
| `caps` | terminfo capabilities answered over XTGETTCAP |
| `charset` | G0/G1 designation and DEC special-graphics line drawing |
| `sgr` | the multi-parameter SGR colour and underline forms |
| `key` | legacy xterm/VT and kitty keyboard-protocol key encoding |
| `mouse` | X10 / UTF-8 / SGR mouse-report encoding |
| `style` | the enums an SGR/DECSET stream selects |
--- | Module | What it covers |
| --------- | ------------------------------------------------------------------------------ |
| `codec` | base64 (OSC 52), hex (XTGETTCAP names), `file://` URI percent-decoding (OSC 7) |
| `caps` | terminfo capabilities answered over XTGETTCAP |
| `charset` | G0/G1 designation and DEC special-graphics line drawing |
| `sgr` | the multi-parameter SGR colour and underline forms |
| `key` | legacy xterm/VT and kitty keyboard-protocol key encoding |
| `mouse` | X10 / UTF-8 / SGR mouse-report encoding |
| `style` | the enums an SGR/DECSET stream selects |
<!--markdownlint-enable MD013-->
## C0 control characters ## C0 control characters
| Byte | Name | Effect | <!--markdownlint-disable MD013-->
| --- | --- | --- |
| `0x07` | BEL | rings the bell (visual flash / command / urgency, per config) | | Byte | Name | Effect |
| `0x08` | BS | backspace | | ------------- | -------- | ------------------------------------------------------------- |
| `0x09` | HT | tab to next stop | | `0x07` | BEL | rings the bell (visual flash / command / urgency, per config) |
| `0x0A`-`0x0C` | LF/VT/FF | line feed | | `0x08` | BS | backspace |
| `0x0D` | CR | carriage return | | `0x09` | HT | tab to next stop |
| `0x0E` | SO | invoke G1 (shift out) | | `0x0A`-`0x0C` | LF/VT/FF | line feed |
| `0x0F` | SI | invoke G0 (shift in) | | `0x0D` | CR | carriage return |
| `0x0E` | SO | invoke G1 (shift out) |
| `0x0F` | SI | invoke G0 (shift in) |
<!--markdownlint-enable MD013-->
## Cursor movement and editing (CSI) ## Cursor movement and editing (CSI)
| Sequence | Name | Effect | <!--markdownlint-disable MD013-->
| --- | --- | --- |
| `CSI Ps A` | CUU | cursor up | | Sequence | Name | Effect |
| `CSI Ps B` / `CSI Ps e` | CUD | cursor down | | ------------------------ | ----------- | ------------------------------------------ |
| `CSI Ps C` / `CSI Ps a` | CUF | cursor forward | | `CSI Ps A` | CUU | cursor up |
| `CSI Ps D` | CUB | cursor back | | `CSI Ps B` / `CSI Ps e` | CUD | cursor down |
| `CSI Ps E` | CNL | cursor down, to column 1 | | `CSI Ps C` / `CSI Ps a` | CUF | cursor forward |
| `CSI Ps F` | CPL | cursor up, to column 1 | | `CSI Ps D` | CUB | cursor back |
| `CSI Ps G` / `CSI Ps \`` | CHA | move to column | | `CSI Ps E` | CNL | cursor down, to column 1 |
| `CSI Ps d` | VPA | move to row | | `CSI Ps F` | CPL | cursor up, to column 1 |
| `CSI Ps ; Ps H` / `f` | CUP/HVP | move to row;col | | `CSI Ps G` / `CSI Ps \`` | CHA | move to column |
| `CSI Ps J` | ED | erase in display (0 below, 1 above, 2 all) | | `CSI Ps d` | VPA | move to row |
| `CSI Ps K` | EL | erase in line (0 right, 1 left, 2 all) | | `CSI Ps ; Ps H` / `f` | CUP/HVP | move to row;col |
| `CSI Ps @` | ICH | insert blank characters | | `CSI Ps J` | ED | erase in display (0 below, 1 above, 2 all) |
| `CSI Ps P` | DCH | delete characters | | `CSI Ps K` | EL | erase in line (0 right, 1 left, 2 all) |
| `CSI Ps L` | IL | insert lines | | `CSI Ps @` | ICH | insert blank characters |
| `CSI Ps M` | DL | delete lines | | `CSI Ps P` | DCH | delete characters |
| `CSI Ps X` | ECH | erase characters | | `CSI Ps L` | IL | insert lines |
| `CSI Ps S` | SU | scroll up | | `CSI Ps M` | DL | delete lines |
| `CSI Ps T` | SD | scroll down | | `CSI Ps X` | ECH | erase characters |
| `CSI Ps ; Ps r` | DECSTBM | set scroll region (top;bottom) | | `CSI Ps S` | SU | scroll up |
| `CSI Ps g` | TBC | clear tab stop (0) or all tabs (3) | | `CSI Ps T` | SD | scroll down |
| `CSI s` / `CSI u` | SCOSC/SCORC | save / restore cursor | | `CSI Ps ; Ps r` | DECSTBM | set scroll region (top;bottom) |
| `CSI Ps g` | TBC | clear tab stop (0) or all tabs (3) |
| `CSI s` / `CSI u` | SCOSC/SCORC | save / restore cursor |
<!--markdownlint-enable MD013-->
## ESC (non-CSI) ## ESC (non-CSI)
| Sequence | Name | Effect | <!--markdownlint-disable MD013-->
| --- | --- | --- |
| `ESC D` | IND | line feed | | Sequence | Name | Effect |
| `ESC M` | RI | reverse index | | --------------------- | ----------- | ------------------------------------------------------------------- |
| `ESC E` | NEL | next line | | `ESC D` | IND | line feed |
| `ESC 7` / `ESC 8` | DECSC/DECRC | save / restore cursor | | `ESC M` | RI | reverse index |
| `ESC H` | HTS | set tab stop | | `ESC E` | NEL | next line |
| `ESC c` | RIS | full reset | | `ESC 7` / `ESC 8` | DECSC/DECRC | save / restore cursor |
| `ESC ( c` / `ESC ) c` | SCS | designate G0 / G1 charset (`0` = DEC special graphics, `B` = ASCII) | | `ESC H` | HTS | set tab stop |
| `ESC c` | RIS | full reset |
| `ESC ( c` / `ESC ) c` | SCS | designate G0 / G1 charset (`0` = DEC special graphics, `B` = ASCII) |
<!--markdownlint-enable MD013-->
## Graphic rendition (SGR, `CSI Ps m`) ## Graphic rendition (SGR, `CSI Ps m`)
@ -85,32 +98,31 @@ Bold (1), dim (2), italic (3), underline (4), blink (5/6), reverse (7), hidden
Underline styles via `4:x` and SGR 21: single, double, curly, dotted, dashed. Underline styles via `4:x` and SGR 21: single, double, curly, dotted, dashed.
Colours: the 16 ANSI colours (30-37, 90-97 foreground; 40-47, 100-107 Colours: the 16 ANSI colours (30-37, 90-97 foreground; 40-47, 100-107
background) and default (39/49). Extended colour for foreground (38), background) and default (39/49). Extended colour for foreground (38), background
background (48), and underline (58/59), in both the legacy semicolon form (48), and underline (58/59), in both the legacy semicolon form (`38;5;n`,
(`38;5;n`, `38;2;r;g;b`) and the colon-subparameter form (`38:5:n`, `38;2;r;g;b`) and the colon-subparameter form (`38:5:n`, `38:2:r:g:b`, with an
`38:2:r:g:b`, with an ignored colour-space id). 256-colour and 24-bit truecolor ignored colour-space id). 256-colour and 24-bit truecolor are fully supported.
are fully supported.
## Modes (DECSET/DECRST `CSI [?] Ps h` / `l`) ## Modes (DECSET/DECRST `CSI [?] Ps h` / `l`)
| Mode | Name | Effect | | Mode | Name | Effect |
| --- | --- | --- | | --------------- | ------- | -------------------------------------- |
| `4` (ANSI) | IRM | insert/replace | | `4` (ANSI) | IRM | insert/replace |
| `?1` | DECCKM | application cursor keys | | `?1` | DECCKM | application cursor keys |
| `?6` | DECOM | origin mode | | `?6` | DECOM | origin mode |
| `?7` | DECAWM | autowrap | | `?7` | DECAWM | autowrap |
| `?25` | DECTCEM | cursor visibility | | `?25` | DECTCEM | cursor visibility |
| `?9` | - | X10 mouse reporting | | `?9` | - | X10 mouse reporting |
| `?1000` | - | normal mouse (press/release) | | `?1000` | - | normal mouse (press/release) |
| `?1002` | - | button-event mouse (drag) | | `?1002` | - | button-event mouse (drag) |
| `?1003` | - | any-event mouse (all motion) | | `?1003` | - | any-event mouse (all motion) |
| `?1004` | - | focus in/out reporting | | `?1004` | - | focus in/out reporting |
| `?1005` | - | UTF-8 mouse coordinates | | `?1005` | - | UTF-8 mouse coordinates |
| `?1006` | - | SGR mouse coordinates | | `?1006` | - | SGR mouse coordinates |
| `?47` / `?1047` | - | alternate screen | | `?47` / `?1047` | - | alternate screen |
| `?1049` | - | alternate screen + save/restore cursor | | `?1049` | - | alternate screen + save/restore cursor |
| `?2004` | - | bracketed paste | | `?2004` | - | bracketed paste |
| `?2026` | - | synchronized output | | `?2026` | - | synchronized output |
Mode state is reportable with **DECRQM** (`CSI [?] Ps $ p`), which replies Mode state is reportable with **DECRQM** (`CSI [?] Ps $ p`), which replies
`CSI [?] Ps ; state $ y` (1 set, 2 reset, 0 unrecognized). `CSI [?] Ps ; state $ y` (1 set, 2 reset, 0 unrecognized).
@ -123,16 +135,20 @@ until an application overrides it.
## Device reports ## Device reports
| Sequence | Name | Reply | <!--markdownlint-disable MD013-->
| --- | --- | --- |
| `CSI c` | DA1 | `CSI ?62;22c` (VT220 + ANSI colour) | | Sequence | Name | Reply |
| `CSI > c` | DA2 | `CSI >0;276;0c` | | -------------------- | --------- | ---------------------------------------------------------- |
| `CSI = c` | DA3 | `DCS !\|00000000 ST` | | `CSI c` | DA1 | `CSI ?62;22c` (VT220 + ANSI colour) |
| `CSI 5 n` | DSR | `CSI 0n` (terminal OK) | | `CSI > c` | DA2 | `CSI >0;276;0c` |
| `CSI 6 n` | CPR | `CSI row;col R` (cursor position) | | `CSI = c` | DA3 | `DCS !\|00000000 ST` |
| `CSI > q` | XTVERSION | `DCS >\|beer(version) ST` | | `CSI 5 n` | DSR | `CSI 0n` (terminal OK) |
| `CSI 6 n` | CPR | `CSI row;col R` (cursor position) |
| `CSI > q` | XTVERSION | `DCS >\|beer(version) ST` |
| `DCS + q <names> ST` | XTGETTCAP | per name, `DCS 1 + r name=value ST` or `DCS 0 + r name ST` | | `DCS + q <names> ST` | XTGETTCAP | per name, `DCS 1 + r name=value ST` or `DCS 0 + r name ST` |
<!--markdownlint-enable MD013-->
XTGETTCAP answers `TN` (terminal name `beer`), `Co`/`colors` (256), and `RGB` XTGETTCAP answers `TN` (terminal name `beer`), `Co`/`colors` (256), and `RGB`
(`8/8/8`, i.e. truecolor). (`8/8/8`, i.e. truecolor).
@ -143,22 +159,26 @@ XTGETTCAP answers `TN` (terminal name `beer`), `Co`/`colors` (256), and `RGB`
## OSC commands ## OSC commands
| Command | Effect | <!--markdownlint-disable MD013-->
| --- | --- |
| `OSC 0` / `OSC 2` | set window title | | Command | Effect |
| `OSC 4 ; idx ; spec` | set / query palette entry (`?` queries) | | --------------------------------- | ------------------------------------------------ |
| `OSC 104 [; idx ...]` | reset palette (all, or listed entries) | | `OSC 0` / `OSC 2` | set window title |
| `OSC 10` / `OSC 11` | set / query default foreground / background | | `OSC 4 ; idx ; spec` | set / query palette entry (`?` queries) |
| `OSC 110` / `OSC 111` | reset foreground / background | | `OSC 104 [; idx ...]` | reset palette (all, or listed entries) |
| `OSC 12` / `OSC 112` | set / reset cursor colour | | `OSC 10` / `OSC 11` | set / query default foreground / background |
| `OSC 17` / `OSC 19` | set / query selection background / foreground | | `OSC 110` / `OSC 111` | reset foreground / background |
| `OSC 7 ; file://host/path` | report working directory (used for new windows) | | `OSC 12` / `OSC 112` | set / reset cursor colour |
| `OSC 8 ; params ; URI` | hyperlink (empty URI ends it) | | `OSC 17` / `OSC 19` | set / query selection background / foreground |
| `OSC 9 ; Pt` | desktop notification (iTerm2 style) | | `OSC 7 ; file://host/path` | report working directory (used for new windows) |
| `OSC 777 ; notify ; title ; body` | desktop notification (rxvt style) | | `OSC 8 ; params ; URI` | hyperlink (empty URI ends it) |
| `OSC 99 ; metadata ; body` | desktop notification (kitty style, single-chunk) | | `OSC 9 ; Pt` | desktop notification (iTerm2 style) |
| `OSC 52 ; target ; data` | clipboard set (base64) or query (`?`) | | `OSC 777 ; notify ; title ; body` | desktop notification (rxvt style) |
| `OSC 133 ; A/B/C/D` | shell-integration prompt marks | | `OSC 99 ; metadata ; body` | desktop notification (kitty style, single-chunk) |
| `OSC 52 ; target ; data` | clipboard set (base64) or query (`?`) |
| `OSC 133 ; A/B/C/D` | shell-integration prompt marks |
<!--markdownlint-enable MD013-->
Colour specs follow the X11 forms `#rrggbb` and `rgb:rr/gg/bb` (1-4 hex digits Colour specs follow the X11 forms `#rrggbb` and `rgb:rr/gg/bb` (1-4 hex digits
per channel). Colour queries reply in the `rgb:rrrr/gggg/bbbb` form. per channel). Colour queries reply in the `rgb:rrrr/gggg/bbbb` form.
@ -179,26 +199,27 @@ tracks the working directory so a new window opens in the same place.
## Keyboard ## Keyboard
The legacy xterm/VT encoding covers cursor keys (with DECCKM application mode), The legacy xterm/VT encoding covers cursor keys (with DECCKM application mode),
the editing keypad (Insert/Delete/PageUp/PageDown), F1-F12, and the the editing keypad (Insert/Delete/PageUp/PageDown), F1-F12, and the xterm
xterm modifier parameter (`CSI 1 ; m <letter>`), with Alt sending an ESC modifier parameter (`CSI 1 ; m <letter>`), with Alt sending an ESC (meta)
(meta) prefix. prefix.
The **kitty keyboard protocol** (`CSI > flags u` push, `CSI < flags u` pop, The **kitty keyboard protocol** (`CSI > flags u` push, `CSI < flags u` pop,
`CSI = flags ; mode u` set, `CSI ? u` query) is implemented with the `CSI = flags ; mode u` set, `CSI ? u` query) is implemented with the
disambiguate, report-event-types, report-alternate-keys, report-all-keys, and disambiguate, report-event-types, report-alternate-keys, report-all-keys, and
report-associated-text enhancement flags. Keys are encoded as `CSI report-associated-text enhancement flags. Keys are encoded as
code[:shifted] ; mod[:event] [; text] u`, with a 32-deep push/pop stack. The `CSI
common keys (Enter, Tab, Backspace) keep their legacy bytes when unmodified so code[:shifted] ; mod[:event] [; text] u`, with a 32-deep push/pop stack.
a plain shell stays usable. The common keys (Enter, Tab, Backspace) keep their legacy bytes when unmodified
so a plain shell stays usable.
## Mouse ## Mouse
Reports are framed in the legacy byte form (`CSI M Cb Cx Cy`), the UTF-8 Reports are framed in the legacy byte form (`CSI M Cb Cx Cy`), the UTF-8
coordinate form (DECSET 1005), or the SGR form (`CSI < Cb ; Cx ; Cy M/m`, coordinate form (DECSET 1005), or the SGR form (`CSI < Cb ; Cx ; Cy M/m`, DECSET
DECSET 1006). Shift/Alt/Ctrl modifier bits and the motion bit are encoded; 1006). Shift/Alt/Ctrl modifier bits and the motion bit are encoded; legacy
legacy releases collapse to button code 3. Reporting level is chosen by the releases collapse to button code 3. Reporting level is chosen by the application
application via the mouse modes above; with reporting off the pointer drives via the mouse modes above; with reporting off the pointer drives local selection
local selection and scrollback. and scrollback.
## POSIX / terminal behaviour ## POSIX / terminal behaviour