kitty has a few extensions to the xterm protocol, to enable advanced features. These are typically in the form of new or re-purposed escape codes. While these extensions are currently kitty specific, it would be nice to get some of them adopted more broadly, to push the state of terminal emulators forward.
The goal of these extensions is to be as small an unobtrusive as possible, while filling in some gaps in the existing xterm protocol. In particular, one of the goals of this specification is explicitly not to "re-imagine" the tty. The tty should remain what it is — a device for efficiently processing text received as a simple byte stream. Another objective is to only move the minimum possible amount of extra functionality into the terminal program itself. This is to make it as easy to implement these protocol extensions as possible, thereby hopefully encouraging their widespread adoption.
If you wish to discuss these extensions, propose additions/changes to them please do so by opening issues in the github bug tracker.
kitty supports colored and styled (wavy) underlines. This is of particular use in terminal editors such as vim and emacs to display red, wavy underlines under mis-spelled words and/or syntax errors. This is done by re-purposing some SGR escape codes that are not used in modern terminals (https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_codes)
To change the underline style from straight line to curl (this used to be the code for rapid blinking text, only previous use I know of was in MS-DOS ANSI.sys):
<ESC>[6m
To set the underline color (this is reserved and as far as I can tell not actually used for anything):
<ESC>[58...m
This works exactly like the codes 38, 48
that are used to set foreground and
background color respectively.
To reset the underline color (also previously reserved and unused):
<ESC>[59m
A client can query if the terminal emulator supports this underline extension using the
standard DECRQM escape sequence, with the
mode value 2016
, like this:
Client sends:
<ESC>[?2016$p
If the terminal supports this underline extension, it must respond with DECRPM
<ESC>[?2016;3$p
See Graphics Protocol for a description of this protocol to enable drawing of arbitrary raster images in the terminal.
There are various problems with the current state of keyboard handling. They include:
-
No way to use modifiers other than
Ctrl
andAlt
-
No way to use multiple modifier keys, other than,
Shift+Alt
. -
No way to handle different types of keyboard events, such as press, release or repeat
-
No reliable way to distinguish single
Esc
keypresses from the start of a escape sequence. Currently, client programs use fragile timing related hacks for this, leading to bugs, for example: neovim #2035
There are already two distinct keyboard handling modes, normal mode and
application mode. These modes generate different escape sequences for the
various special keys (arrow keys, function keys, home/end etc.) Most terminals
start out in normal mode, however, most shell programs like bash
switch them to
application mode. We propose adding a third mode, named full mode that addresses
the shortcomings listed above.
Switching to the new full mode is accomplished using the standard private mode DECSET escape sequence
<ESC>[?2017h
and to leave full mode, use DECRST
<ESC>[?2017l
The number 2017
above is not used for any existing modes, as far as I know.
Client programs can query if the terminal emulator is in full mode by using
the standard DECRQM escape sequence.
The new mode works as follows:
-
All printable key presses without modifier keys are sent just as in the normal mode. This means all printable ASCII characters and in addition,
Enter
,Space
andBackspace
. Also any unicode characters generated by platform specific extended input modes, such as using theAltGr
key. This is done so that client programs that are not aware of this mode can still handle basic text entry, so if a full mode using program crashes and does not reset, the user can still issue areset
command in the shell to restore normal key handling. Note that this includes pressing theShift
modifier and printable keys. -
For non printable keys and key combinations including one or more modifiers, an escape sequence encoding the key event is sent. For details on the escape sequence, see below.
The escape sequence encodes the following properties:
-
Type of event:
press,repeat,release
-
Modifiers pressed at the time of the event
-
The actual key being pressed
<ESC>_K<type><modifiers><key><ESC>\
Where <type>
is one of p
— press, r
— release and t
— repeat.
Modifiers is a bitmask represented as a single base64 digit. Shift — 0x1
,
Alt — 0x2
, Control — 0x4
and Super — 0x8
. <key>
is a number
(encoded in base85) corresponding to the key pressed. The key name to number
mapping is defined in this table.
For example:
<ESC>_KpGp<ESC>\ is <Ctrl>+<Alt>+x (press)
<ESC>_KrP8<ESC>\ is <Ctrl>+<Alt>+<Shift>+<Super>+PageUp (release)
This encoding means each key event is represented by 8 or 9 printable ascii only bytes, for maximum robustness.