hterm Control Sequences

Like every terminal out there, hterm supports a number of standard (and perhaps not so standard) control/escape sequences. This doc outlines hterm's position on everything -- things that are supported, things that will never be supported, etc...

It's not meant to be a comprehensive guide to a terminal. For that, please see the References section.

Parsing of these sequences are contained entirely in hterm_vt.js, and the character maps are defined in hterm_vt_character_map.js.

For TBD entries, it means we haven‘t put in the work to implement the feature yet, but we generally wouldn’t be adverse to adding it. Or we haven‘t quite figured out how best to do so. Or we just haven’t thought about it at all to say no :).

Similarly for entries marked as passed thru -- we might do something with them in the future, but currently we just print it.

However, for entries marked “won't support”, it means we don't consider them relevant and will probably never be implemented.

If you come across missing features or have other requests, feel free to file a bug at

General Guidelines

We aim to be compliant with:

  • ECMA-35 (Character Code Structure and Extension Techniques): covers some fundamentals related to character sets, the notions of C0, C1, G0, etc... (but not their contents), and how escape sequences work (but not what they mean). This is equivalent to ISO/IEC 2022.
  • ECMA-43 (8-bit Coded Character Set Structure and Rules): Builds on top of ECMA-35 by defining the character sets (e.g. 0x40 == @). This is equivalent to ISO/IEC 4873.
  • ECMA-48 (Control Functions for Coded Character Sets): Builds on top of ECMA-35 by defining many of the common escape sequences. Supersedes the ANSI codes, and is equivalent to ISO/IEC 6429.
  • ISO/IEC 8613-6 (Character content architectures): Builds on top of ECMA-35 by defining fonts and graphic renditions (e.g. SGR). This is equivalent to ITU T.416.

Going beyond those basics, we use these sites for guidance:

  • XTerm: Canonical terminal emulator in the X world.
  • Spec sheets for VT100 and similar terminals.

C0 Control Codes

These are the basic characters in the 0x00 - 0x1F range.

While DEL (0x7F) isn't actually part of C0, we list it here for convenience.

^A0101SOHStart of HeadingPassed thru
^B0202STXStart of TextPassed thru
^C0303ETXEnd of TextPassed thru
^D0404EOTEnd of TransmissionPassed thru
^F0606ACKAcknowledgePassed thru
^I0909HT\tCharacter Tabulation (Horizontal Tabulation)Supported
^J100ALF\nLine FeedSupported
^K110BVT\vLine Tabulation (Vertical Tabulation)Converted to LF (\n)
^L120CFF\fForm FeedConverted to LF (\n)
^M130DCR\rCarriage ReturnSupported
^N140ESO/LS1Shift Out / Locking Shift OnePoint GL to G1
^O150FSI/LS0Shift In / Locking Shift ZeroPoint GL to G0
^P1610DLEData Link EscapePassed thru
^Q1711DC1Device Control One (XON)Ignored (TBD)
^R1812DC2Device Control TwoPassed thru
^S1913DC3Device Control Three (XOFF)Ignored (TBD)
^T2014DC4Device Control FourPassed thru
^U2115NAKNegative AcknowledgePassed thru
^V2216SYNSynchronous IdlePassed thru
^W2317ETBEnd of Transmission BlockPassed thru
^X2418CANCancelSupported (1)
^Y2519EMEnd of mediumPassed thru
^Z261ASUBSubstituteConverted to CAN
^[271BESC\eEscapeSupported (2)
^\281CFS/IS4File Separator / Information Separator FourPassed thru
^]291DGS/IS3Group Separator / Information Separator ThreePassed thru
^^301ERS/IS2Record Separator / Information Separator TwoPassed thru
^_311FUS/IS1Unit Separator / Information Separator OnePassed thru

  1. Used to cancel escape sequences, and to change GL back to G0.
  2. ESC is a multiplexed command; see section below for more details.

C1 Control Codes

These are some extended characters in the 0x80 - 0x9F range.

Since these don‘t play well with UTF-8 encoding, they’re typically accessed via an escape sequence. e.g. ESC+@ (0x1b 0x40) instead of 0x80.

@12880PADPadding CharacterIgnored (TBD)
A12981HOPHigh Octet PresetIgnored (TBD)
B13082BPHBreak Permitted HereIgnored (TBD)
C13183NBHNo Break HereIgnored (TBD)
D13284INDIndexLike newline, but keep column position
E13385NELNext LineLike newline, but doesn't add a line
F13486SSAStart of Selected AreaWon't support
G13587ESAEnd of Selected AreaIgnored (TBD)
H13688HTSCharacter Tabulation SetSets horizontal tab stop at the column
I13789HTJCharacter Tabulation With JustificationIgnored (TBD)
J1388AVTSLine Tabulation SetIgnored (TBD)
K1398BPLDPartial Line ForwardIgnored (TBD)
L1408CPLUPartial Line BackwardIgnored (TBD)
M1418DRIReverse Line FeedMove up one line keeping column position
N1428ESS2Single-Shift TwoIgnored
O1438FSS3Single-Shift ThreeIgnored
P14490DCSDevice Control StringIgnored (TBD) (1)
Q14591PU1Private Use OneIgnored (TBD)
R14692PU2Private Use TwoIgnored (TBD)
S14793STSSet Transmit StateIgnored (TBD)
T14894CCHCancel characterIgnored (TBD)
U14995MWMessage WaitingIgnored (TBD)
V15096SPAStart of Guarded AreaWon't support
W15197EPAEnd of Guarded AreaWon't support
X15298SOSStart of StringWon't support
Y15399SGCISingle Graphic Character IntroducerIgnored (TBD)
Z1549ASCISingle Character IntroducerSends [?1;2c
[1559BCSIControl Sequence IntroducerSupported (2)
\1569CSTString TerminatorUsed to terminate escape sequences
]1579DOSCOperating System CommandSupported (3)
^1589EPMPrivacy MessageWon't support
_1599FAPCApplication Program CommandWon't support

  1. DCS is a multiplexed command; see section below for more details.
  2. CSI is a multiplexed command; see section below for more details.
  3. OSC is a multiplexed command; see section below for more details.

G0/G1/G2/G3 Graphic Codesets for GL/GR (SCS)

Support for character maps may be disabled at runtime via DOCS.

With the rise of UTF-8 encoding, graphic codesets have fallen out of favor. Although we still support a limited number for legacy systems.

Basically, instead of seeing things like “w” or “#”, you'll see “┬” or “£”. These were used to get basic graphics (like border lines), or to support other 7-bit character sets (like German characters ß and ü).

The terminal has 4 graphic codeset slots (named G0, G1, G2, and G3), and 2 pointers (GL and GR) to those slots. The active display then uses those pointers to determine what is shown. Both the slots and pointers can be updated at any time.

The GR pointer, while tracked, does not actually get processed. When running in a UTF8 environment, it's easy to corrupt codeunits in a codepoint leading to bad output.

We don't currently differentiate between 94-character sets and 96-character sets. Although all of the maps we support are within the 94-char range.

As for the character sets that you can actually load, we support some hard character sets, but not all of them. We do not support soft character sets.

Here's the list of national replacement character sets (NRCS) we support:

BUnited States (ASCII)
CFinnish (same as “5” above)
ENorwegian/Danish (same as “6” above)
HSwedish (same as “7” above)
QFrench Canadian

Designate Other Coding System (DOCS)

ECMA-35 supports changing the encoding system of terminal. Since hterm is natively UTF-8, we use this to control support for character maps (see SCS for more details).

This escape sequence has a one or two byte form. If the first byte is /, then it is a one way transition. i.e. Any further attempts to change the encoding will simply be ignored. This is useful for putting the terminal into UTF-8 mode permanently and not worrying about binary data switching character maps to graphics mode.

To invoke these, use ESC+%+DOCS. e.g. ESC+%/G (0x1b 0x25 0x2f 0x47).

Any sequence not documented below is simply ignored. The only two byte sequence supported currently is where the first byte is /.

DOCSDescriptionCharacter Maps (SCS)
@Switch to ECMA-35 encoding (default)Supported
GSwitch to UTF-8 encodingSupported
/GPermanently switch to UTF-8 encoding Level 1Treated as /I
/HPermanently switch to UTF-8 encoding Level 2Treated as /I
/IPermanently switch to UTF-8 encoding Level 3Supported

Escape Sequences

These are other escape sequences we support. This is similar to the C1 Control Codes space, but there is only a two byte sequence. e.g. ESC+# (0x1b 0x23).

Some of these may have subcommands, so it might end up being a three byte sequence where the 3rd byte is further interpreted. We refer to that as arg1 in the Action column below.

SPIgnored (TBD)
!Ignored (TBD)
"Ignored (TBD)
$Ignored (TBD)
%DOCSDesignate Other Coding SystemSupported
&Ignored (TBD)
'Ignored (TBD)
(SCSSet G0 character set (VT100)Set G0 to NRCS arg1
)SCSSet G1 character set (VT220)Set G1 to NRCS arg1
*SCSSet G2 character set (VT220)Set G2 to NRCS arg1
+SCSSet G3 character set (VT220)Set G3 to NRCS arg1
,Ignored (TBD)
-SCSSet G1 character set (VT300)Set G1 to NRCS arg1
.SCSSet G2 character set (VT300)Set G2 to NRCS arg1
/SCSSet G3 character set (VT300)Set G3 to NRCS arg1
0Ignored (TBD)
1Ignored (TBD)
2Ignored (TBD)
3Ignored (TBD)
4Ignored (TBD)
5Ignored (TBD)
6DECBIBack IndexIgnored (TBD)
7DECSCSave CursorSupported
8DECRCRestore CursorSupported
9DECFIForward IndexIgnored (TBD)
:Ignored (TBD)
;Ignored (TBD)
<Ignored (TBD)
=DECKPAMKeypad Application ModeSupported
>DECKPNMKeypad Numeric ModeSupported
?Ignored (TBD)
@See C1 Control Codes
ASee C1 Control Codes
BSee C1 Control Codes
CSee C1 Control Codes
DSee C1 Control Codes
ESee C1 Control Codes
FSee C1 Control Codes
GSee C1 Control Codes
HSee C1 Control Codes
ISee C1 Control Codes
JSee C1 Control Codes
KSee C1 Control Codes
LSee C1 Control Codes
MSee C1 Control Codes
NSee C1 Control Codes
OSee C1 Control Codes
PSee C1 Control Codes
QSee C1 Control Codes
RSee C1 Control Codes
SSee C1 Control Codes
TSee C1 Control Codes
USee C1 Control Codes
VSee C1 Control Codes
WSee C1 Control Codes
XSee C1 Control Codes
YSee C1 Control Codes
ZSee C1 Control Codes
[See C1 Control Codes
\See C1 Control Codes
]See C1 Control Codes
^See C1 Control Codes
_See C1 Control Codes
`DMIDisable Manual InputIgnored (TBD)
aINTInterruptIgnored (TBD)
bEMIEnable Manual InputIgnored (TBD)
cRISReset to Initial StateResets terminal state
dCMDCoding Method DelimiterIgnored (TBD)
eIgnored (TBD)
fIgnored (TBD)
gIgnored (TBD)
hIgnored (TBD)
iIgnored (TBD)
jIgnored (TBD)
kSet tmux window nameSupported (1)
lMemory lock/unlockWon't support
mMemory lock/unlockWon't support
nLS2Locking Shift TwoPoint GL to G2
oLS3Locking Shift ThreePoint GL to G3
pIgnored (TBD)
qIgnored (TBD)
rIgnored (TBD)
sIgnored (TBD)
tIgnored (TBD)
uIgnored (TBD)
vIgnored (TBD)
wIgnored (TBD)
xIgnored (TBD)
yIgnored (TBD)
zIgnored (TBD)
{Ignored (TBD)
|LS3RLocking Shift Three RightIgnored (Point GR to G3)
}LS2RLocking Shift Two RightIgnored (Point GR to G2)
~LS1RLocking Shift One RightIgnored (Point GR to G1)

  1. This is different from window title. See the tmux manual. It does nothing by default.


A few random escape sequences. They are initiated with ESC+#.

3DECDHLDouble-Width, Double-Height Line (Top Half)Ignored
4DECDHLDouble-Width, Double-Height Line (Bottom Half)Ignored
5DECSWLSingle-Width, Single-Height LineIgnored
6DECDWLDouble-Width, Single-Height LineIgnored
8DECALNScreen Alignment PatternFill terminal with E's

Device Control String (DCS)

Device Control String is not currently supported which means none of its subcommands work either (like ReGIS or Sixel).

Operating System Command (OSC)

This is a grab bag of various escape sequences. They are initiated with ESC+]. Arguments to the sequences are typically delimited by ;, and terminated with BEL. e.g. ESC+] 0 ; title BEL (0x1b 0x5d 0x30 0x3b ... 0x07).

For example:

0Set window title & icon nameOnly window titleESC ] 0 ; [title] \a
1Change icon nameIgnoredESC ] 1 ; [icon] \a
2Set window titleConverted to 0ESC ] 2 ; [title] \a
3Set X propertyIgnored
4Set/read color paletteSupportedESC ] 4 ; index1;rgb1;...;indexN;rgbN \a
5Change special color numberIgnored
6Enable special color numberIgnored
6Set current file pathIgnored
7Set current directoryIgnoredESC ] 7 ; directory \a
8Set hyperlinkSupportedESC ] 8 ; id=foo ; uri \a text ESC ] 8 ;; \a
9iTerm2 Growl notificationsSupportedESC ] 9 ; [message] \a
10Set foreground colorSupportedESC ] 10 ; [X11 color spec] \a
11Set background colorSupportedESC ] 11 ; [X11 color spec] \a
12Set text cursor colorSupportedESC ] 12 ; [X11 color spec] \a
13Set mouse foreground colorIgnoredESC ] 13 ; [X11 color spec] \a
14Set mouse background colorIgnoredESC ] 14 ; [X11 color spec] \a
15Set Tektronix foreground colorIgnoredESC ] 15 ; [X11 color spec] \a
16Set Tektronix background colorIgnoredESC ] 16 ; [X11 color spec] \a
17Set highlight background colorIgnoredESC ] 17 ; [X11 color spec] \a
18Set Tektronix cursor colorIgnoredESC ] 18 ; [X11 color spec] \a
19Set highlight foreground colorIgnoredESC ] 19 ; [X11 color spec] \a
46Set logfile pathIgnoredESC ] 46 ; path \a
50Change font number/nameIgnoredESC ] 50 ; [number
50Set the cursor shapeSupportedESC ] 50 ; CursorShape=[0|1|2] \a
51Reserved for EmacsIgnored
52Clipboard operationsOnly “c” supportedESC ] 52 ; c ; [base64 data] \a
104Reset color numberSupportedESC ] 104 ; index1;...;indexN \a
105Reset special color numberIgnored
106Enable special color numberIgnored
110Reset foreground colorSupportedESC ] 110 ; \a
111Reset background colorSupportedESC ] 111 ; \a
112Reset text cursor colorSupportedESC ] 112 ; \a
113Reset mouse foreground colorIgnoredESC ] 113 ; \a
114Reset mouse background colorIgnoredESC ] 114 ; \a
115Reset Tektronix foreground colorIgnoredESC ] 115 ; \a
116Reset Tektronix background colorIgnoredESC ] 116 ; \a
117Reset highlight background colorIgnoredESC ] 117 ; \a
118Reset Tektronix cursor colorIgnoredESC ] 118 ; \a
119Reset highlight foreground colorIgnoredESC ] 119 ; \a
777rxvt-unicode (urxvt) modulesOnly “notify” supportedESC ] 777 ; notify ; [title] ; [body] \a
1337iTerm2 sequencesOnly “File” supportedESC ] 1337 ; File = [args] : [base64 data] \a

OSC+1337: iTerm2 sequences

The iTerm2 terminal for macOS provides a lot of proprietary options via the OSC 1337 command. Many of them duplicate other standard sequences, so most of them aren't supported.

We support media display and file transfers. This is specified via the File= keyword. None of the options below are required as a reasonable default will be selected automatically.

There is a helper script you can use to handle the protocol for you.
Warning: You should avoid transferring larger files as Chrome performance will suffer. If it's under 2 MB, it probably will be fine, but YMMV.

The overall form looks like ESC+] 1337 ; File=name=[base64];inline=1 : [base64 data] BEL.

  • name: The base64 encoded name of the file or other human readable text.
  • size: How many bytes in the base64 data (for transfer progress).
  • width: The display width specification (see below). Defaults to auto.
  • height: The display height specification (see below). Defaults to auto.
  • preserveAspectRatio: If 0, scale/stretch the display to fit the space. If 1 (the default), fill the display as much as possible without stretching.
  • inline: If 0 (the default), download the file instead of displaying it. If 1, display the file in the terminal.
  • align: Set the display alignment with left (the default), right, or center.
  • type: Set the MIME type of the content. Auto-detected otherwise.

For the base64 encoded fields, make sure to omit whitespace (e.g. newlines) if using a tool like base64.

For the width & height fields, a number of forms are accepted. Note that the terminal will probably restrict the maximum size automatically to the active terminal dimensions. e.g. If the terminal is 1000 pixels wide, specifying a width greater than that will automatically be limited to 1000 pixels.

  • N: How many cells (e.g. rows or columns) to fill.
  • Npx: How many pixels to fill.
  • N%: A percentage of the overall terminal screen.
  • auto: Use the file's dimension.

For inline display, currently only images in formats Chrome itself understands are supported.

Control Sequence Introducer (CSI)

These are various color and cursor related escape sequences. Also referred to as ANSI escape sequences. They are initiated with ESC+[. Arguments to the sequences are typically delimited by ; and precede the command. e.g. ESC+[ arg1 ; arg2 ; argN m.

The final command is a single character in the range 0x40 (@) through 0x7F (~). That's a limited space, so the command can be further refined with characters immediately following the ESC+[ bytes. Those may be in the range 0x20 () through 0x3F (?), excluding the range 0x30 (0) through 0x39 (9) and 0x3A (:) and 0x3B (;). e.g. The CSI command ?$p command below takes the form ESC+[ ? $ arg1 ; arg2 ; argN p.

@ICHInsert Blank CharactersAdd space
ACUUCursor UpMove cursor up arg1 rows
BCUDCursor DownMove cursor down arg1 rows
CCUFCursor ForwardMove cursor forward arg1 columns
DCUBCursor BackwardMove cursor back arg1 columns
ECNLCursor Next LineMove cursor down arg1 rows and to first column
FCPLCursor Preceding LineMove cursor up arg1 rows and to first column
GCHACursor Horizontal AbsoluteMove cursor to arg1 column
HCUPCursor PositionMove cursor to arg1 row and arg2 column
ICHTCursor Forward TabulationMove cursor forward arg1 tabs
JEDErase in Display!arg1 or arg1 == 0: Clear cursor to end of display
arg1 == 1: Clear start of display to cursor
arg1 == 2: Clear display
arg1 == 3: Clear scrollback
?JDECSEDSelective Erase in DisplaySame as ED above
KELErase in Line!arg1 or arg1 == 0: Clear cursor to end of line
arg1 == 1: Clear start of line to cursor
arg1 == 2: Clear line
?KDECSELSelective Erase in LineSame as EL above
LILInsert LinesInsert arg1 lines
MDLDelete LinesDelete arg1 lines
NEFErase in FieldIgnored (TBD)
OEAErase in AreaIgnored (TBD)
PDCHDelete CharactersDelete arg1 characters before cursor
QSEESelect Editing ExtentIgnored (TBD)
RCPRActive Position ReportIgnored (TBD)
SSUScroll UpScroll up arg1 lines
TSDScroll DownScroll down arg1 lines
>TWon't support
UNPNext PageIgnored (TBD)
VPPPrevious PageIgnored (TBD)
WCTCCursor Tabulation ControlIgnored (TBD)
XECHErase CharactersDelete arg1 characters after cursor
YCVTCursor Line TabulationIgnored (TBD)
ZCBTCursor Backward TabulationMove cursor back arg1 tabs
[SRSStart Reversed StringIgnored (TBD)
\PTXParallel TextsIgnored (TBD); See Ruby character
]SDSStart Directed StringIgnored (TBD)
^SIMDSelect Implicit Movement DirectionIgnored (TBD)
_Ignored (TBD)
`HPACharacter Position AbsoluteSame as CHA above
aHPRCharacter Position RelativeMove cursor forward arg1 columns
bREPRepeatIgnored (TBD)
cDA/DA1Send Primary Device AttributesCurrently reports “VT100 with Advanced Video Option”
>cDA2Send Secondary Device AttributesCurrently reports “VT100”
dVPALine Position AbsoluteMove cursor to arg1 row
eVPRLine Position ForwardIgnored (TBD)
fHVPHorizontal and Vertical PositionSame as CUP above
gTBCTab Clear!arg1 or arg1 == 0: Clear tab stop at cursor
arg1 == 3: Clear all tab stops
hSMSet ModeSupported (1)
?hDECSETDEC Set ModeSupported (2)
iMCMedia CopyWon't support
?iDECMCDEC Media CopyWon't support
jHPBCharacter Position BackwardIgnored (TBD)
kVPBLine Position BackwardIgnored (TBD)
lRMReset ModeSupported (1)
?lDECRSTDEC Mode ResetSupported (2)
mSGRSelect Graphic RenditionSupported (3)
>mxterm specific keyboard modesWon't support
nDSRDevice Status ReportsSupported
?nDECDSRDEC Device Status ReportsSupported
>nxterm specific modifiersWon't support
oDAQDefine Area QualificationIgnored (TBD)
pIgnored (TBD)
>pxterm specific cursor display controlIgnored (TBD)
!pDECSTRSoft Terminal ResetSupported
$pDECRQMRequest Mode - Host To TerminalIgnored (TBD)
?$pDECRQMRequest Mode - Host To TerminalIgnored (TBD)
"pDECSCLSelect Conformance LevelIgnored (TBD)
qDECLLLoad LEDsIgnored (TBD)
␠qDECSCUSRSet Cursor StyleSupported
"qDECSCASelect Character Protection AttributeWon't support
rDECSTBMSet Top and Bottom MarginsSupported
?rRestore DEC Private Mode ValuesWon't support
$rDECCARAChange Attributes in Rectangular AreaWon't support
sSave cursor (ANSI.SYS)Supported
?sSave DEC Private Mode ValuesWon't support
tWindow manipulationPartial support
$tDECRARAReverse Attributes in Rectangular AreaWon't support
>tSet one or more features of the title modesWon't support
␠tDECSWBVSet Warning Bell VolumeWon't support
uRestore cursor (ANSI.SYS)Supported
␠uDECSMBVSet Margin Bell VolumeWon't support
vIgnored (TBD)
$vDECCRACopy Rectangular AreaWon't support
wIgnored (TBD)
'wDECEFREnable Filter RectangleWon't support
xDECREQTPARMRequest Terminal ParametersIgnored (TBD)
*xDECSACESelect Attribute Change ExtentWon't support
$xDECFRAFill Rectangular AreaWon't support
yIgnored (TBD)
zvt_tiledataTile dataSemi-Supported
'zDECELREnable Locator ReportingIgnored (TBD)
$zDECERAErase Rectangular AreaWon't support
{Ignored (TBD)
'{DECSLESelect Locator EventsIgnored (TBD)
|Ignored (TBD)
'|DECRQLPRequest Locator PositionIgnored (TBD)
}Ignored (TBD)
'}DECICInsert ColumnWon't support
~Ignored (TBD)
'~DECDCDelete ColumnWon't support

  1. SM/RM are multiplexed commands; see section below for more details.
  2. DECSET/DECRST are multiplexed commands; see section below for more details.
  3. SGR is a multiplexed command; see section below for more details.

Modes (SM) / (RM)

Ignoring the use of the generic word “mode”, the Set Mode and Reset Mode commands are used to control different operating modes. Historically these made sense with a wide range of hardware devices that used different binary protocols, but nowadays we can ignore most as dead code. That is why hterm doesn't support most of these.

For SM, the specified mode is enabled. For RM, it's disabled (reset).

1GATMGuarded Area Transfer ModeWon't support
2KAMKeyboard Action ModeWon't support
3CRMControl Representation ModeIgnored
4IRMInsertion Replacement ModeSupported
5SRTMStatus Report Transfer ModeIgnored
6ERMERasure modeIgnored
7VEMLine Editing ModeIgnored
8BDSMBi-Directional Support ModeIgnored
9DCSMDevice Component Select ModeIgnored
10HEMCharacter Editing ModeIgnored
11PUMPositioning Unit ModeIgnored
12SRMSend/Receive ModeWon't support
13FEAMFormat Effector Action ModeIgnored
14FETMFormat Effector Transfer ModeIgnored
15MATMMultiple Area Transfer ModeIgnored
16TTMTransfer Termination ModeIgnored
17SATMSelected Area Transfer ModeIgnored
18TSMTabulation Stop ModeIgnored
20LNMAutomatic NewlineSupported
21GRCMGraphic Rendition Combination ModeIgnored
22ZDMZero Default ModeIgnored

Private Modes (DECSET) / (DECRST)

Similar to the SM & RM commands, these are extensions that DEC added to their VT's. Then other people started adding their own. There are many, and we support some of them.

1DECCKMDECApplication Cursor KeysSupported
2DECANMDECDesignate USASCII for character sets G0-G3, and set VT100 modeIgnored (TBD)
3DECCOLMDEC132 Column ModeSupported
4DECSCLMDECSmooth (Slow) ScrollWon't support
5DECSCNMDECReverse VideoSupported
6DECOMDECOrigin ModeSupported
7DECAWMDECWraparound ModeSupported
8DECARMDECAuto-repeat KeysWon't support
9X10 MOUSEXSend Mouse X & Y on button pressSupported
10rxvtShow toolbarWon't support
12att610Start blinking cursorSupported
18DECPFFDECPrint form feedIgnored (TBD)
19DECPEXDECSet print extent to full screenWon't support
25DECTCEMDECShow CursorSupported
30rxvtShow scrollbarSupported
35rxvtEnable font-shifting functionsWon't support
38DECTEKDECEnter Tektronix ModeWon't support
40Allow 80 - 132 (DECCOLM) ModeSupported
41cursesmore(1) fixIgnored (TBD)
42DECNRCMDECEnable Nation Replacement Character setsIgnored (TBD)
44Turn On Margin BellIgnored (TBD)
45Reverse-wraparound ModeSupported
46Start LoggingIgnored (TBD)
47Use Alternate Screen BufferSupported
66DECNKMDECApplication keypadIgnored (TBD)
67DECBKMDECBackarrow key sends backspaceSupported
1000MOUSE_REPORT_CLICKXSend Mouse X & Y on button press and releaseSupported
1001Use Hilite Mouse TrackingIgnored (TBD)
1002MOUSE_REPORT_DRAGUse Cell Motion Mouse TrackingSupported
1003Use All Motion Mouse TrackingIgnored (TBD)
1004Send FocusIn/FocusOut eventsSupported
1005Enable Extended Mouse Mode (UTF-8)Supported
1006Enable Extended Mouse Mode (SGR)Supported
1007xtermEnable Alternate Scroll ModeSupported
1010rxvtScroll to bottom on tty outputSupported
1011rxvtScroll to bottom on key pressSupported
1015rxvtEnable Extended Mouse Mode (urxvt)Won't support
1034Interpret “meta” key, sets eighth bitWon't support
1035Enable special modifiers for Alt and NumLock keysWon't support
1036Send ESC when Meta modifies a keySupported
1037Send DEL from the editing-keypad Delete keyIgnored (TBD)
1039Send ESC when Alt modifies a keySupported
1040Keep selection even if not highlightedWon't support
1041Use the CLIPBOARD selectionWon't support
1042Enable Urgency window manager hint when Ctrl+G is receivedIgnored (TBD)
1043Enable raising of the window when Ctrl+G is receivedIgnored (TBD)
1047Use Alternate Screen BufferSupported
1048Save cursor as in DECSCSupported
1049Combine 1047 and 1048 modes and clearSupported
1050Set terminfo/termcap function-key modeIgnored (TBD)
1051Set Sun function-key modeWon't support
1052Set HP function-key modeWon't support
1053Set SCO function-key modeWon't support
1060Set legacy keyboard emulation (X11R6)Won't support
1061Set VT220 keyboard emulationIgnored (TBD)
2004Set bracketed paste modeSupported

Mouse Reporting / Tracking

These are the sequences that the terminal generates based on mouse events the user themselves create. The terminal sends them to the remote so the application can handle mouse inputs. These could be things as simple as clicking different mouse buttons in different terminal rows/cols, or more complicated things like click & drag, or wheel scrolling.

There are a few different mouse reporting modes in the wild. Here we document all the modes that hterm currently supports. It‘s unlikely we’ll support more modes unless they offer significant functionality over the existing modes.

Some of the modes seem to overlap, but they can largely be broken down into two different aspects: what is reported (presses/drags/etc...) and how is the message encoded. The terminal first calculates the values to report (via the reporting mode), then the values are encoded before being sent to the remote.

By default, no mouse reporting is enabled, so all mouse events are handled by the native implementation (e.g. for copying content or clicking links). If mouse reporting is enabled, it by default uses the X10 encoding.

If you want to enable mouse reporting, you should always use the SGR encoding. For reporting modes, most people want to start with the xterm extensions (so they get mouse press & release events, wheel scrolls, and keyboard modifiers).

Reporting Modes

Only mouse buttons 1 (primary aka left), 2 (secondary aka right), 3 (middle), 4 (wheel up), and 5 (wheel down) can be reported. All other buttons are ignored.


This is the simplest and oldest mode: only mouse button presses are reported; no releases, and no motion/drags. It is enabled via DECSET 9.

The mouse button is the button number minus 1.

X11 / xterm

Reporting is extended to support mouse button releases and keyboard modifiers. It is enabled via DECSET 1000.

The mouse button status is in the bottom two bits. Only SGR supports reporting which mouse button was released (see the SGR encoding section below for more details).

  • 0: Mouse button 1 is pressed.
  • 1: Mouse button 2 is pressed.
  • 2: Mouse button 3 is pressed.
  • 3: The mouse button was released.

The keyboard modifiers are encoded in bits 2, 3, and 4. They indicate which keyboard keys were held down. There is no way to detect keyboard presses/releases directly.

  • bit 2: The shift key.
  • bit 3: The meta key.
  • bit 4: The control key.
Cell / Button Event Tracking

Reporting is extended to support motion events while buttons are held down. It is enabled via DECSET 1002.

Motion Event Tracking

Reporting is extended to support motion events regardless of button state. It is enabled via DECSET 1003.

This is not currently supported as most programs do not use it or care. It can end up transmitting a lot of data when the mouse is constantly moved.

Encoding Modes

If you're unsure which encoding to select, then use SGR.

In >=hterm-1.85, we limit to 95 rows and columns due to encoding limitations.

There is a limit of 223 rows and columns due to the protocol encoding: they made sure that each byte of data was printable, so 32 was added (which is the first printable ASCII character). There is also an 8-bit encoding limit, so 255 is the largest value.

This is the default encoding if no other selection has been made. You should really use SGR instead though.

The encoding takes the form of CSI M Cb Cx Cy where:

  • Each value has 32 added to it.
  • Cb is the button & keyboard modifiers.
  • Cx is the column (between 0 and 223).
  • Cy is the row (between 0 and 223).
UTF-8 (Extended)

This is like the X10 form, but since we can assume UTF-8 encoding, the row and column limit is increased to 2047. The values still had 32 added to them. Hence it is often referred to as “UTF-8” or “extended” encoding modes.

It is enabled via DECSET 1005.

The encoding takes the form of CSI M Cb Cx Cy where:

  • Each field is encoded in UTF-8.
  • Each value has 32 added to it.
  • Cb is the button & keyboard modifiers.
  • Cx is the column (between 0 and 2047).
  • Cy is the row (between 0 and 2047).

This is the preferred encoding format as there are no row or column limits.

This can easily be confused with the Select Graphic Rendition (SGR) naming, but that's no coincidence: they use similar encoding formats with semi-colon delimited numbers.

Since the value is always printable (by virtue of being a number), there is no need to add 32 to each value.

It is enabled via DECSET 1006.

The encoding takes the form of CSI < Cb ; Cx ; Cy M when a button is pressed, and CSI < Cb ; Cx ; Cy m when a button is released, where:

  • Each field is encoded as an ASCII integer.
  • Cb is the button & keyboard modifiers.
  • Cx is the column.
  • Cy is the row.

The only other notable encoding at this time is urxvt‘s, but since its encoding is ambiguous with other CSI sequences, we won’t support it. The SGR encoding supports everything that urxvt tried to do too.

It is enabled via DECSET 1015.

Wheel Mice

Since the mouse reporting can only handle 3 buttons normally, wheel up (button 4) is encoded as mouse button 1 with 64 added to it. Wheel down (button 5) is mouse button 2 with 64 added to it.

No release events are generated.

Wheel mice events are always enabled when mouse reporting is active.

Alternate Scroll Mode

Instead of generating mouse events, the mouse wheel can be configured to emit up/down/left/right arrow key presses instead. This is useful when working with applications that don't understand mouse reporting, but do handle arrow keys fine.

This mode is only active when the alternate screen is enabled. Otherwise, the mouse wheel is used to control local buffer scrolling.

It is enabled via DECSET 1007.

Select Graphic Rendition (SGR)

These are various color and cursor related escape sequences. Also referred to as ANSI escape sequences. They are initiated with ESC+[ and finish with the m command. Accepts an arbitrary number of args delimited by ; and in any order.

SGRCharacter AttributeAction
Enable Attributes
0Normal (default)Supported
1Bold (increased intensity)Supported
2Faint (decreased intensity)Supported
4UnderlinedSupported (2)
5Blink (slowly)Supported
6Rapid blinkIgnored (TBD)
7Inverse (negative image)Supported
9Crossed outSupported
10Primary fontIgnored
11First alternative fontIgnored
12Second alternative fontIgnored
13Third alternative fontIgnored
14Fourth alternative fontIgnored
15Fifth alternative fontIgnored
16Sixth alternative fontIgnored
17Seventh alternative fontIgnored
18Eighth alternative fontIgnored
19Ninth alternative fontIgnored
20ReservedIgnored (TBD)
21Double underlinedSupported
Disable Attributes
22Normal (decorations)Supported
23Not italicSupported
24Not underlinedSupported
25Steady (not blink)Supported
26Variable spacingIgnored (TBD)
27Positive image (not inverse)Supported
28Visible (not invisible)Supported
29Not crossed outSupported
Foreground Color
30Set foreground color to BlackSupported
31Set foreground color to RedSupported
32Set foreground color to GreenSupported
33Set foreground color to YellowSupported
34Set foreground color to BlueSupported
35Set foreground color to MagentaSupported
36Set foreground color to CyanSupported
37Set foreground color to WhiteSupported
38Set foreground color to extended colorSupported (1)
39Set foreground color to default (original)Supported
Background Color
40Set background color to BlackSupported
41Set background color to RedSupported
42Set background color to GreenSupported
43Set background color to YellowSupported
44Set background color to BlueSupported
45Set background color to MagentaSupported
46Set background color to CyanSupported
47Set background color to WhiteSupported
48Set background color to extended colorSupported (1)
49Set background color to default (original)Supported
50Not variable spacingIgnored (TBD)
51FramedIgnored (TBD)
52EncircledIgnored (TBD)
53OverlinedIgnored (TBD)
54Not framed and not encircledIgnored (TBD)
55Not overlinedIgnored (TBD)
56ReservedIgnored (TBD)
57ReservedIgnored (TBD)
58Set underline color to extended colorSupported (1)
59Set underline color to default (original)Supported
60Ideogram underline or right side lineIgnored (TBD)
61Ideogram double underline or double right side lineIgnored (TBD)
62Ideogram overline or left side lineIgnored (TBD)
63Ideogram double overline or double left side lineIgnored (TBD)
64Ideogram stress markingIgnored (TBD)
65Cancel SGR 60 through 64Ignored (TBD)
Bright Foreground Color
90Set foreground color to bright BlackSupported
91Set foreground color to bright RedSupported
92Set foreground color to bright GreenSupported
93Set foreground color to bright YellowSupported
94Set foreground color to bright BlueSupported
95Set foreground color to bright MagentaSupported
96Set foreground color to bright CyanSupported
97Set foreground color to bright WhiteSupported
Bright Background Color
100Set background color to bright BlackSupported
101Set background color to bright RedSupported
102Set background color to bright GreenSupported
103Set background color to bright YellowSupported
104Set background color to bright BlueSupported
105Set background color to bright MagentaSupported
106Set background color to bright CyanSupported
107Set background color to bright WhiteSupported

Note that most terminals consider “bold” to be “bold and bright”. In some documents the bold state is even referred to as bright. We interpret bold as bold-bright here too, but only when the “bold” setting comes before the color selection.


In addition to the standard underline sequences, we support some non-standard sequences to enable more styles and coloring. We'll cover the non-standard sequences here only.

  • 4:0: Turn off underlining (same as SGR+24).
  • 4:1: Underline with a single solid line (same as the normal 4).
  • 4:2: Underline with double lines (same as SGR+21).
  • 4:3: Underline with a single wavy/curvy line.
  • 4:4: Underline with a single dotted line.
  • 4:5: Underline with a single dashed line.

In addition to the style, you can change the color by using SGR+58 (which uses the same syntax as SGR+38/SGR+48, and clear the color by using SGR+59 (which uses the same syntax as SGR+39/SGR+49).

SGR+38/SGR+48: Extended Colors

These color sequences support both the ISO/IEC 8613-6 form (i.e. colon delimited) and, because of wide legacy usage, some xterm specific forms (i.e. semi-colon delimited). It's likely that other emulators do not support the ISO/IEC 8613-6 forms fully.

There are multiple extended color choices available.

  • 0: Implementation defined. We ignore it.
  • 1: Transparent color.
  • 2: RGB color (a.k.a. true color or 24-bit color).
  • 3: CMY color. We don't support it yet.
  • 4: CMYK color. We don't support it yet.
  • 5: Select color by palette index (a.k.a. 8-bit or 88-color or 256-color).

Implementation & Transparent Colors

For 0 and 1, we require the ISO/IEC 8613-6 form.

  • 38 : 0 -- Do nothing to the foreground!
  • 48 : 0 -- Do nothing to the background!
  • 38 : 1 -- Make the foreground transparent.
  • 48 : 1 -- Make the background transparent.

RGB/True/24-bit Colors

For RGB colors, the ISO/IEC 8613-6 forms apply. The 2nd argument is left blank as it is the color space identifier which we ignore. We also ignore the trailing tolerance and color space arguments.

  • 38 : 2 : : R : G : B -- Set foreground color to rgb(R, G, B).
  • 48 : 2 : : R : G : B -- Set background color to rgb(R, G, B).

We also support the legacy xterm forms for compatibility.

  • 38 ; 2 ; R ; G ; B -- Only RGB is specified, and uses semi-colons.
  • 48 ; 2 ; R ; G ; B -- Same as above.
  • 38 : 2 : R : G : B -- Only RGB is specified using colons.
  • 48 : 2 : R : G : B -- Same as above.

We do not support the mixed xterm form as no one else seems to either, or has actively decided to drop support for it.

  • 38 ; 2 : R : G : B -- Mixes semi-colon & colon arguments.
  • 48 ; 2 : R : G : B -- Same as above.


CMY is not yet supported.

For CMY and CMYK colors, we require the ISO/IEC 8613-6 form. The 2nd argument is left blank as it is the color space identifier which we ignore. We also ignore the trailing tolerance and color space arguments.

  • 38 : 3 : : C : M : Y -- Set foreground color to CMY color.
  • 48 : 3 : : C : M : Y -- Set background color to CMY color.
  • 38 : 4 : : C : M : Y : K -- Set foreground color to CMYK color.
  • 48 : 4 : : C : M : Y : K -- Set background color to CMYK color.

Palette/8-bit/88/256 Colors

For palette based colors (8-bit/88-colors/256-colors), the ISO/IEC 8613-6 forms apply.

  • 38 : 5 : P -- Set foreground color using a palette index.
  • 48 : 5 : P -- Set background color using a palette index.

We also support the legacy xterm forms for compatibility.

  • 38 ; 5 ; P -- Uses semi-colons instead of colons.
  • 48 ; 5 ; P -- Same as above.

We do not support the mixed xterm form as no one else seems to either, or has actively decided to drop support for it.

  • 38 ; 5 : P -- Mixes semi-colon & colon arguments.
  • 48 ; 5 : P -- Same as above.