^[control-codes live in libghostty-vt

ANSI modes

IRM Insertion Replacement Mode

Insert characters instead of writing over them.

CSI 4 h
ECMA-48
§7.2.10 IRM – Insertion Replacement Mode, p. 24
DEC STD 070
§5.11 Insert/Replacement Mode, p. 5-138
VT220
§4.6.4 Insert/Replace Mode (IRM)
VT510
IRM—Insert/Replace Mode
xterm
Functions using CSI

Mode 4 decides what a printed character does to the one under the cursor.

StateECMA-48 calls itMeaning
Reset, CSI 4 lREPLACEthe character takes the place of the one under the cursor
Set, CSI 4 hINSERTthe character is inserted, and the rest of the line moves right

Replace is the default. 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. Only printing is affected: the controls and the erasing functions work as they always do.

xterm keeps the mode (ansi_modes), and so does libghostty-vt, and both answer DECRQM with its state.

Validation

IRM-1: Insert mode

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

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

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

IRM-3: Back to replace mode

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

IRM-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__|

IRM-5: Reset by default

\e[4$p
|_____|
reply \e[4;2$y

IRM-6: Set

\e[4h
\e[4$p
|_____|
reply \e[4;1$y
Every example on these pages runs in your browser, in libghostty-vt compiled to WebAssembly.