^[control-codes live in libghostty-vt

ANSI modes

TSM Tabulation Stop Mode

Whether a tab stop applies to every line or only one.

CSI 18 h
ECMA-48
§7.2.17 TSM – Tabulation Stop Mode, p. 25
DEC STD 070
§5.10.1.3 Modes That Cannot Be Changed, p. 5-134

Mode 18 decides whether setting or clearing a tab stop, with HTS, TBC or CTC, does so in that column of every line, or only in the line the cursor is on.

StateECMA-48 calls itMeaning
Reset, CSI 18 lMULTIPLEin every line
Set, CSI 18 hSINGLEin the active line only

DEC STD 070 §5.10.1.3, p. 5-134 lists it among the X3.64 modes a DEC terminal may treat as fixed, as reset. The VT510 manual’s table of modes for DECRPM marks it as always reset. In xterm, as on a DEC terminal, a tab stop belongs to a column, the same on every line.

xterm ignores CSI 18 h and CSI 18 l (ansi_modes handles only modes 2, 4, 12 and 20), and DECRQM reports the mode as permanently reset, 4 (do_ansi_rqm). libghostty-vt ignores it too, but does not recognize the number, so it answers DECRQM with 0. Both DECRQM cases are known differences.

Validation

TSM-1: Reported as permanently reset

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

TSM-2: Even after it is set

\e[18h
\e[18$p
|_____|
reply \e[18;4$y

TSM-3: A tab stop still applies to every line

\e[3g       # clear every tab stop
\e[18h     # ignored
\e[1;4H
\eH         # set a stop in line 1
\e[2;1H
\t
X
|______|
|___X__|
cursor 2,5
Every example on these pages runs in your browser, in libghostty-vt compiled to WebAssembly.