^[control-codes live in libghostty-vt

Control sequences

SM Set Mode

Turn terminal modes on and off.

CSI Pm h
ECMA-48
§8.3.125 SM – Set Mode, p. 65
DEC STD 070
§5.10.1 SM/RM – Set Mode, Reset Mode, p. 5-133
VT510
SM—Set Mode

CSI Pm h (SM) sets one or more modes, and CSI Pm l (RM) resets them. Each parameter names one mode, and ECMA-48 gives no default. RM is ECMA-48 §8.3.106, p. 56 and RM—Reset Mode in the VT510 manual.

ECMA-48 numbers 22 modes, most of them for data transmission, editing devices and bidirectional text. DEC STD 070 lists the four a DEC terminal accepts, and libghostty-vt accepts the same four. The defaults are libghostty-vt’s:

PmModeSetReset
2KAM, keyboard actionkeyboard lockedkeyboard unlocked (default)
4IRM, insertion/replacementinsertreplace (default)
12SRM, send/receiveno local echo (default)local echo
20LNM, line feed/new lineLF, VT and FF also returnLF, VT and FF only move down (default)

KAM and SRM concern the keyboard, so they have no effect on the screen and no cases here.

IRM. In replace mode, which is the default, a printed character takes the place of the one under the cursor. In insert mode, the character under the cursor and everything right of it move one column right to make room, and whatever is pushed past the right margin is lost. DEC STD 070 defines it at §5.11, p. 5-138, and the VT510 manual as IRM.

LNM. With LNM set, a line feed, vertical tab or form feed also moves the cursor to the first column, as CR LF would. DEC STD 070 defines it at §5.4.4, p. 5-57, and says that conforming software should not set it; the VT510 manual describes it as LNM. ECMA-48 removed it in this fifth edition, having deprecated it in the fourth, and mode 20 is now “shall not be used”, but DEC terminals, and libghostty-vt, still have it.

ANSI modes and DEC private modes cannot be mixed in one sequence. The DEC private form, CSI ? Pm h and CSI ? Pm l (DECSET and DECRST), takes a different set of mode numbers and is not covered on this page.

Validation

SM-1: Insert mode

abc
\e[1;1H
\e[4h     # IRM
X
|Xabc__|
cursor 1,2

SM-2: What is pushed off the line is lost

ABCDEF    # fills the line
\e[1;2H
\e[4h     # IRM
X
|AXBCDE|
|______|
cursor 1,3

SM-3: Back to replace mode

abc
\e[1;1H
\e[4h     # IRM: insert
X
\e[4l     # replace
Y         # over the a
|XYbc__|

SM-4: Insert stops at the right margin

\e[1;5H
abcdef            # columns 5 to 10
\e[?69h           # allow left and right margins
\e[5;10s          # margins at columns 5 and 10
\e[1;7H
\e[4h             # IRM
X                 # the f is pushed past column 10
|____abXcde__|

SM-5: Line feed/new line mode

\e[20h    # LNM
AB
\n
C
\e[20l
\n
D
|AB___|
|C____|
|_D___|