Control Sequences

Control sequences are a way for programs to interact with the terminal.

Control sequences are used to do things like move the cursor, change text color, clear the screen, and more. They are the primary way that programs interact with the terminal.

Programs running within terminals only have a single way to communicate with the terminal: writing bytes to the connected file descriptor (typically a pseudo-terminal, or a "pty" for short). In order to differentiate between text to be displayed and commands to be executed, terminals use special syntax known collectively as control sequences.

Each type of control sequence has a different format and purpose. They are described below along with their specific syntax. The reference contains a full list of supported control sequences grouped by type.

C0 control characters

Each control sequence starts with a special, unprintable character, known as a control character. The simplest control characters, known as C0 control characters, lie between 0x00 and 0x20 in the ASCII encoding and take no parameters other than themselves.

There are very few control characters, but they're important to be aware of because the single byte value impacts the terminal state.

C0 characters meaningful to terminal emulation include:

C0AbbrFull nameFunction
0x07BELBellRaise the attention of the user.
0x08BSBackspaceMove the cursor backward one position.
0x09TABTabMove the cursor right to the next tab stop.
0x0ALFLinefeedMove the cursor down one line.
0x0DCRCarriage ReturnMove the cursor to the leftmost column.

Escape sequences

One of the C0 characters, Escape (0x1b, ESC), is special. It can either start a few discrete sequences or begin entire families of sequences, which is also why control sequences are also pars pro toto commonly known as escape sequences.

Not all sequences that begin with Escape are Escape sequences as defined here (they are more likely to be C1 sequences), but a true Escape sequence like ESC D are in the format below.

esc_sequence = "0x1B" intermediates final
intermediates = [0x20-0x2F]*
final = [0x30-0x7E]

Fe sequences

When Escape is followed by certain printable characters, for various historical reasons they are instead interpreted together as C1 control characters, some of which are responsible for many families of sequences known collectively as Fe sequences. These characters can also be represented by single 8-bit characters, but they remain predominantly encoded with Escape characters as to avoid conflicting with UTF-8 and other high-byte encodings usually used in modern terminals.

ESC codeC1AbbrFull nameFunction
ESC [0x9bCSIControl Sequence IntroducerBy far the most common. Uses integers to control the cursor, the screen, modes, cells, and their styles.
ESC ]0x9dOSCOperating System CommandOften used in modern terminal extensions to transmit string data.
ESC P0x90DCSDevice Control SequenceMost often used when querying the terminal's capabilities (XTGETTCAP). Rare otherwise.
ESC _0x9fAPCApplication Program CommandUsed in very complex protocols like the Kitty Graphics Protocol that require arbitrary payloads.
ESC X0x98SOSStart of StringObsolete. Ignored by Ghostty.
ESC ^0x9ePMPrivate MessageObsolete. Ignored by Ghostty.

CSI

CSI sequences are by far the most common type of C1 sequences. They use integer parameters separated either with colons (:) or semicolons (;) to move the cursor, set the terminal's mode, scroll up or down, insert and delete cells and lines, change the styles of cells, etc.

Their primary limitation is that they can only encode integer values. Other sequence types such as OSC or DCS are needed to encode string data.

CSI sequences follow the format below. An example CSI sequence is ESC [ 1 ; 2 m.

csi_sequence = "0x1B" "[" params intermediates final
params = param | param sep params
param = [0-9]
sep = ";" | ":"
intermediates = [0x20-0x2F]*
final = [0x40-0x7E]

OSC

OSC sequences are typically used to encode strings or other non-integer data to transmit between the terminal and an application. They usually alter variables regarding the terminal emulator itself, such as its title, palette, clipboard, etc., or instruct it on extra features like hyperlinks, progress reports, the current working directory, and so on.

As a result of its flexibility, OSC sequences are very often used by modern extensions to offer new functionality that older terminals can simply ignore.

An OSC sequence begins with OSC (ESC ] or 0x9d). Then, by convention, an integer is added to identify the operation

The format of an OSC sequence is below. By convention, OSC sequences are identified by an integer identifier followed by a semicolon (;), although this is never required by the standard. Certain obsolete OSC sequences use non-numeric identifiers before the semicolon, but Ghostty does not support

Note

Due to yet more convoluted historical reasons, OSC sequences in xterm (and by extension Ghostty) may be terminated with the Bell character (BEL, 0x07) instead of the standard String Terminator (ST, ESC \ or 0x9c).

While they are in most cases interchangeable, Ghostty will try to echo back the terminator used in an OSC sequence when replying, to ensure maximum compatibility with older programs and terminals. New code should always prefer ST due to standards compliance.

them. An example OSC sequence is OSC 2 ; 👻 Ghostty 👻 ST (where ST is the String Terminator).

osc_sequence = "0x1B" "]" data terminator
data = [0x20-0xFF]
terminator = "0x1B" "0x5C"

DCS

DCS Sequences are like a CSI sequence combined with an OSC sequence: they natively support integer parameters as well as string values. An example DSC sequence is DCS + P q <string> ST

dsc_sequence = "0x1B" "P" params intermediates final data ST
params = param | param ";" params
param = [0-9]
intermediates = [0x20-0x2F]*
final = [0x40-0x7E]
data = [0x20-0xFF]
ST = "0x1B" "0x5C"

APC

Ghostty supports APC sequences. Currently there is only one supported APC sequence: the Kitty Graphics Protocol sequence. This is documented here.

apc_sequence = "0x1B" "_" data ST
data = [0x20-0xFF]
ST = "0x1B" "0x5C"

SOS and PM

SOS and PM sequences are entirely ignored by Ghostty.

sos_sequence = "0x1B" "X" data ST
pm_sequence = "0x1B" "^" data ST
data = [0x20-0xFF]
ST = "0x1B" "0x5C"