#+TITLE: Zutty key mapping sequences
#+OPTIONS: author:nil timestamp:nil toc:nil num:nil val:nil html-style:nil H:3 ^:{}
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="org.css"/>

This is a summary of the character sequences Zutty emits in response
to various special keys, and how this mapping depends on the state of
the terminal.

* Mode settings affecting the emitted sequences

| Mode     | Description                       | Setting   |
|----------+-----------------------------------+-----------|
| DECANM   | VT52 Mode                         | CSI ? 2 l |
| DECANM   | VT100 mode                        | CSI ? 2 h |
| DECCKM/N | Cursor Key Mode: Normal/Cursor    | CSI ? 1 l |
| DECAKM/A | Cursor Key Mode: Application      | CSI ? 1 h |
| DECKPNM  | Normal/Numeric Keypad Mode        | ESC >     |
| DECKPAM  | Alternate/Application Keypad Mode | ESC =     |

* Effect of modifier keys

In case of modifiers being held while a key is pressed, a derived
sequence is sent that includes a Modifier Code as an additional (last)
parameter of the original sequence. If the original sequence did not
start with CSI, the start is changed to CSI (with the exception of
keypad keys). If there were no original parameters in the sequence, a
first default parameter of 1 is added before appending the Modifier
Code.

Modifier codes:

| Modifier(s)           | Code |
|-----------------------+------|
| Shift                 |    2 |
| Alt                   |    3 |
| Alt + Shift           |    4 |
| Control               |    5 |
| Control + Shift       |    6 |
| Control + Alt         |    7 |
| Control + Alt + Shift |    8 |

To make it clearer, in each section we will include some examples of
what sequences will result when some modifiers are applied.

Modifiers are generally not applicable to VT52 mode, but are uniform
across ANSI and keypad modes.

* Sequences that are the same regardless of state

| Key                      | Sequence |
|--------------------------+----------|
| Insert, KP_Insert        | CSI 2 ~  |
| Delete, KP_Delete        | CSI 3 ~  |
| Prior (PageUp), KP_Prior | CSI 5 ~  |
| Next (PageDown), KP_Next | CSI 6 ~  |

Modifier examples:
- Shift + Insert: CSI 2 ; 2 ~
- Control + PageUp: CSI 5 ; 5 ~

Modifiers work even in VT52 mode.

* Function keys

These are independent of cursor key and numeric keypad modes.

| Key       | VT100     | VT52      |
|-----------+-----------+-----------|
| F1, KP_F1 | SS3 P     | ESC P     |
| F2, KP_F2 | SS3 Q     | ESC Q     |
| F3, KP_F3 | SS3 R     | ESC R     |
| F4, KP_F4 | SS3 S     | ESC S     |
| F5        | CSI 1 5 ~ | CSI 1 5 ~ |
| F6        | CSI 1 7 ~ | CSI 1 7 ~ |
| F7        | CSI 1 8 ~ | ...       |
| F8        | CSI 1 9 ~ |           |
| F9        | CSI 2 0 ~ |           |
| F10       | CSI 2 1 ~ |           |
| F11       | CSI 2 3 ~ |           |
| F12       | CSI 2 4 ~ |           |
| F13       | CSI 2 5 ~ |           |
| F14       | CSI 2 6 ~ |           |
| F15       | CSI 2 8 ~ |           |
| F16       | CSI 2 9 ~ |           |
| F17       | CSI 3 1 ~ |           |
| F18       | CSI 3 2 ~ |           |
| F19       | CSI 3 3 ~ |           |
| F20       | CSI 3 4 ~ |           |

Modifier examples:
- Shift + F1: CSI 1 ; 2 P
- Alt + F4: CSI 1 ; 3 S
- Shift + F5: CSI 1 5 ; 2 ~
- Control + Shift + F10: CSI 21 ; 6 ~

Modifiers are not applied in VT52 mode.

* Sequences dependent on cursor key mode setting

| Key             | VT100 Normal | VT100 App | VT52  |
|-----------------+--------------+-----------+-------|
| Up, KP_Up       | CSI A        | SS3 A     | ESC A |
| Down, KP_Down   | CSI B        | SS3 B     | ESC B |
| Right, KP_Right | CSI C        | SS3 C     | ESC C |
| Left, KP_Left   | CSI D        | SS3 D     | ESC D |
| KP_Begin        | CSI E        | SS3 E     | ESC E |
| Home, KP_Home   | CSI H        | SS3 H     | ESC H |
| End, KP_End     | CSI F        | SS3 F     | ESC F |

Examples (apply both in Normal and App mode):
- Alt + Left: CSI 1 ; 3 D
- Control + Home: CSI 1 ; 5 H

Modifiers are not applied in VT52 mode.

* Sequences dependent on keypad mode setting

This only affects the keypad. The corresponding non-keypad keys always
send the characters in the Normal column. Normal (aka. numeric) mode
is shared between VT100 and VT52.

Some keys are received from X with different keysyms based on the
NumLock state; for these keys, the second column shows the keysym with
NumLock off.  With NumLock on, all keys generate their literals (as in
normal mode).  With NumLock off, mappings are generated as below,
depending on the terminal mode setting.

| NumLock on   | NumLock off  | Normal | VT100 App | VT52 App |
|--------------+--------------+--------+-----------+----------|
| KP_Space     |              | SP     | SS3 SP    | ESC ? SP |
| KP_Tab       |              | TAB    | SS3 I     | ESC ? I  |
| KP_Enter     |              | CR     | SS3 M     | ESC ? M  |
| KP_Multiply  |              | *      | SS3 j     | ESC ? j  |
| KP_Add       |              | +      | SS3 k     | ESC ? k  |
| KP_Separator |              | ,      | SS3 l     | ESC ? l  |
| KP_Subtract  |              | -      | SS3 m     | ESC ? m  |
| KP_Decimal   | KP_Delete    | .      | SS3 n     | ESC ? n  |
| KP_Divide    |              | /      | SS3 o     | ESC ? o  |
| KP_0         | KP_Insert    | 0      | SS3 p     | ESC ? p  |
| KP_1         | KP_End       | 1      | SS3 q     | ESC ? q  |
| KP_2         | KP_Down      | 2      | SS3 r     | ESC ? r  |
| KP_3         | KP_Page_Down | 3      | SS3 s     | ESC ? s  |
| KP_4         | KP_Left      | 4      | SS3 t     | ESC ? t  |
| KP_5         | KP_Begin     | 5      | SS3 u     | ESC ? u  |
| KP_6         | KP_Right     | 6      | SS3 v     | ESC ? v  |
| KP_7         | KP_Home      | 7      | SS3 w     | ESC ? w  |
| KP_8         | KP_Up        | 8      | SS3 x     | ESC ? x  |
| KP_9         | KP_Page_Up   | 9      | SS3 y     | ESC ? y  |
| KP_Equal     |              | =      | SS3 X     | ESC ? X  |

The intention is that Zutty behaves just like xterm with
[[https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-VT220-Style-Function-Keys][VT220-style function keys]].

In VT100 App mode, modifier keys do NOT cause the SS3 to change to
CSI. This is how xterm behaves, and Zutty emulates that behaviour.

Examples:
- Control + KP_Enter: SS3 5 M
- Control + KP_Plus: SS3 5 k
- Alt + KP_Minus: SS3 3 m

Modifiers are not applied in VT52 mode.

* Special key combinations

The resource settings =altSendsEscape= and =modifyOtherKeys= (modeled
after xterm) control how /other/ key combinations (not specified in the
above tables) are encoded.

The encoding rules are, by and large, meant to be the same as that of
xterm; please refer to its extensive documentation for details. As a
complement, below we present several example key encodings for
different values of =modifyOtherKeys= (columns 0, 1 and 2), with an
=altSendsEscape= setting of true (the default).

| Key                         | 0          | 1                 | 2                  |
|-----------------------------+------------+-------------------+--------------------|
| Shift-a                     | A          | A                 | CSI 27 ; 2 ; 65 ~  |
| Shift-Space                 | Space      | Space             | CSI 27 ; 2 ; 32 ~  |
| Shift-TAB                   | CSI Z      | CSI Z             | CSI 27 ; 2 ; 9 ~   |
| Shift-Return                | Return     | CSI 27 ; 2 ; 13 ~ | CSI 27 ; 2 ; 13 ~  |
| Control-Space               | ^@         | ^@                | CSI 27 ; 5 ; 32 ~  |
| Control-Alt-Space           | ESC ^@     | ESC ^@            | CSI 27 ; 7 ; 32 ~  |
| Control-Shift-Space         | ^@         | ^@                | CSI 27 ; 6 ; 32 ~  |
| Control-Alt-Shift-Space     | ESC ^@     | ESC ^@            | CSI 27 ; 8 ; 32 ~  |
| Control-TAB                 | TAB        | CSI 27 ; 5 ; 9 ~  | CSI 27 ; 5 ; 9 ~   |
| Control-Return              | Return     | CSI 27 ; 5 ; 13 ~ | CSI 27 ; 5 ; 13 ~  |
| Control-Alt-Return          | ESC Return | CSI 27 ; 7 ; 13 ~ | CSI 27 ; 7 ; 13 ~  |
| Control-Alt-Shift-Return    | ESC Return | CSI 27 ; 8 ; 13 ~ | CSI 27 ; 8 ; 13 ~  |
| Control-0                   | 0          | CSI 27 ; 5 ; 48 ~ | CSI 27 ; 5 ; 48 ~  |
| Control-1                   | 1          | CSI 27 ; 5 ; 49 ~ | CSI 27 ; 5 ; 49 ~  |
| Control-2                   | ^@         | ^@                | CSI 27 ; 5 ; 50 ~  |
| Control-3                   | ESC        | ESC               | CSI 27 ; 5 ; 51 ~  |
| Control-4                   | ^\         | ^\                | CSI 27 ; 5 ; 52 ~  |
| Control-5                   | ^]         | ^]                | CSI 27 ; 5 ; 53 ~  |
| Control-6                   | ^^         | ^^                | CSI 27 ; 5 ; 54 ~  |
| Control-7                   | ^_         | ^_                | CSI 27 ; 5 ; 55 ~  |
| Control-8                   | DEL        | DEL               | CSI 27 ; 5 ; 56 ~  |
| Control-9                   | 9          | CSI 27 ; 5 ; 57 ~ | CSI 27 ; 5 ; 57 ~  |
| Control-! (Control-Shift-1) | !          | CSI 27 ; 6 ; 33 ~ | CSI 27 ; 6 ; 33 ~  |
| Control-@ (Control-Shift-2) | ^@         | ^@                | CSI 27 ; 6 ; 64 ~  |
| Control-# (Control-Shift-3) | #          | CSI 27 ; 6 ; 35 ~ | CSI 27 ; 6 ; 35 ~  |
| Control-$ (Control-Shift-4) | $          | CSI 27 ; 6 ; 36 ~ | CSI 27 ; 6 ; 36 ~  |
| Control-% (Control-Shift-5) | %          | CSI 27 ; 6 ; 37 ~ | CSI 27 ; 6 ; 37 ~  |
| Control-^ (Control-Shift-6) | ^^         | ^^                | CSI 27 ; 6 ; 94 ~  |
| Control-& (Control-Shift-7) | &          | CSI 27 ; 6 ; 38 ~ | CSI 27 ; 6 ; 38 ~  |
| Control-* (Control-Shift-8) | *          | CSI 27 ; 6 ; 42 ~ | CSI 27 ; 6 ; 42 ~  |
| Control-( (Control-Shift-9) | (          | CSI 27 ; 6 ; 40 ~ | CSI 27 ; 6 ; 40 ~  |
| Control-) (Control-Shift-0) | )          | CSI 27 ; 6 ; 41 ~ | CSI 27 ; 6 ; 41 ~  |
| Control-c                   | ^C         | ^C                | CSI 27 ; 5 ; 99 ~  |
| Control-d                   | ^D         | ^D                | CSI 27 ; 5 ; 100 ~ |
| Control-i                   | TAB        | TAB               | CSI 27 ; 5 ; 105 ~ |
| Control-Shift-I             | TAB        | TAB               | CSI 27 ; 6 ; 73 ~  |
| Control-x                   | ^X         | ^X                | CSI 27 ; 5 ; 120 ~ |
| Control-Alt-x               | ESC ^X     | ESC ^X            | CSI 27 ; 7 ; 120 ~ |
| Control-Shift-D             | ^D         | ^D                | CSI 27 ; 6 ; 68 ~  |
| Control-Alt-Shift-D         | ESC ESC    | ESC ESC           | CSI 27 ; 8 ; 68 ~  |
| Control-;                   | ;          | CSI 27 ; 5 ; 59 ~ | CSI 27 ; 5 ; 59 ~  |
| Control-: (Control-Shift-;) | :          | CSI 27 ; 6 ; 58 ~ | CSI 27 ; 6 ; 58 ~  |
| Control-\                   | ^\         | ^\                | CSI 27 ; 5 ; 92 ~  |
| Control-¦ (Control-Shift-\) | ^\         | ^\                | CSI 27 ; 6 ; 124 ~ |
| Control-`                   | ^@         | ^@                | CSI 27 ; 5 ; 96 ~  |
| Control-~ (Control-Shift-`) | ^^         | ^^                | CSI 27 ; 6 ; 126 ~ |
| Alt-Space                   | ESC Space  | ESC Space         | CSI 27 ; 3 ; 32 ~  |
| Alt-Shift-Space             | ESC Space  | ESC Space         | CSI 27 ; 4 ; 32 ~  |
| Alt-TAB                     | ESC TAB    | ESC TAB           | CSI 27 ; 3 ; 9 ~   |
| Alt-Return                  | ESC Return | CSI 27 ; 3 ; 13 ~ | CSI 27 ; 3 ; 13 ~  |
| Alt-Shift-Return            | ESC Return | CSI 27 ; 4 ; 13 ~ | CSI 27 ; 4 ; 13 ~  |
| Alt-d                       | ESC d      | ESC d             | CSI 27 ; 3 ; 100 ~ |
| Alt-Shift-d                 | ESC D      | ESC D             | CSI 27 ; 4 ; 68 ~  |
| Alt-x                       | ESC x      | ESC x             | CSI 27 ; 3 ; 120 ~ |
| Alt-Shift-X                 | ESC X      | ESC X             | CSI 27 ; 4 ; 88 ~  |
