^[control-codes live in libghostty-vt

Control sequences

XTSAVE Save DEC Private Mode Values

Remember the state of some private modes, to put back later.

CSI ? Pm s
xterm
Functions using CSI

CSI ? Pm s saves the state of each private mode it names, and XTRESTORE, CSI ? Pm r, puts it back. A program that needs a mode for a while, say autowrap off while it draws a status line, can save the mode, change it, and restore it afterwards without having to know how it was set to begin with. It changes no mode itself.

Only xterm defines it: DEC’s terminals had nothing like it, and none of ECMA-48, DEC STD 070 or the VT220 and VT510 manuals mentions it. Its parameters are private mode numbers, the same as DECSET’s, and the ? is what keeps it apart from another sequence with the same final byte. Without the ?, CSI s is DECSLRM, or saves the cursor.

xterm’s own description calls it a one-level cache, like DECSC’s: each mode has one saved state, and saving it again replaces it. Unlike DECSC, the modes are saved one by one, and only the ones named. xterm saves each in turn in savemodes, which knows nearly every private mode it has; a number it does not know is skipped. libghostty-vt keeps one saved state per mode the same way.

Validation

XTSAVE-1: Save, change, and restore

\e[?7s     # save autowrap, which is on
\e[?7l
\e[?7r
ABCDEFG
|ABCDE|
|FG___|
cursor 2,3

XTSAVE-2: Saving changes nothing

\e[?7l
\e[?7s
ABCDEFG
|ABCDG|
|_____|
cursor 1,5

XTSAVE-3: Several modes in one sequence

\e[?7;25s  # autowrap and the cursor
\e[?7;25l
\e[?7;25r
\e[?7$p
\e[?25$p
|_____|
reply \e[?7;1$y\e[?25;1$y

XTSAVE-4: A second save replaces the first

\e[?7s     # on
\e[?7l
\e[?7s     # off, in place of on
\e[?7h
\e[?7r
ABCDEFG
|ABCDG|
|_____|
cursor 1,5
Every example on these pages runs in your browser, in libghostty-vt compiled to WebAssembly.