^[control-codes live in libghostty-vt

Control sequences

DECCARA Change Attributes in Rectangular Area

Change or reverse the rendition of a rectangle of the screen without rewriting its characters.

CSI Pt ; Pl ; Pb ; Pr ; Pm $ r
Defaults
the whole screen; Pm = 0
DEC STD 070
§5.12.1 Change Attributes Rectangular Area, p. 5-173
VT510
DECCARA—Change Attributes in Rectangular Area

Three functions that change how characters already on the screen look, without writing them again:

SequenceFunctionDoes
CSI Pt ; Pl ; Pb ; Pr ; Pm $ rDECCARAsets or clears attributes
CSI Pt ; Pl ; Pb ; Pr ; Pm $ tDECRARAreverses attributes: turns each one on where it is off, and off where it is on
CSI Ps * xDECSACEchooses which cells the other two change

The first four parameters are a rectangle’s corners, as for DECERA: left out or 0 they take the screen’s edge, and only origin mode brings the margins into it. The rest are SGR parameters. DECCARA takes 0, which clears them all, 1, 4, 5 and 7 to set bold, underline, blink and inverse, and 22, 24, 25 and 27 to clear one of them; xterm adds 8 and 28 for invisible. DECRARA takes 0, which reverses them all, and 1, 4, 5 and 7, with xterm again adding 8. Colors are not changed, and neither is the current rendition that later text is written in. DEC STD 070 defines DECRARA at §5.12.1, p. 5-175 and DECSACE at p. 5-177; the VT510 manual has DECRARA and DECSACE.

DECSACE chooses the extent. With Ps 0 or 1, the default, the change runs as a stream: from the first corner to the end of its line, across the whole of every line in between, and up to the second corner on the last line, like a selection in a text editor. Cells nothing has been written to are skipped. With Ps 2, it is the exact rectangle, and empty cells in it become blanks that take the change. That is xterm’s ScrnMarkRectangle, following DEC STD 070, and a host can read the setting back with DECRQSS.

Not in libghostty-vt

These are VT420 rectangle operations, level 4 in DEC STD 070. libghostty-vt, a VT220 (see DA), has no handler for CSI … $ r, CSI … $ t or CSI … * x in stream.zig, and ignores all three. xterm is a VT420 by default and implements them (CASE_DECSACE, CASE_DECCARA, CASE_DECRARA), so every case below expects xterm’s result and is a known difference (see the sources page).

Validation

DECCARA-1: Bold, in a rectangle

abcdef\r\nghijkl\r\nmnopqr
\e[2*x    # DECSACE: rectangle
\e[1;2;2;4;1$r
|abcdef|
|ghijkl|
|mnopqr|
attr 1,2 bold
attr 2,4 bold
attr 1,1 -bold
attr 1,5 -bold
attr 2,1 -bold

DECCARA-2: The same, as a stream

abcdef\r\nghijkl\r\nmnopqr
\e[1;2;2;4;1$r # DECSACE is a stream by default
|abcdef|
|ghijkl|
|mnopqr|
attr 1,1 -bold
attr 1,6 bold
attr 2,1 bold
attr 2,4 bold
attr 2,5 -bold

DECCARA-3: Zero clears every attribute

\e[1;4;7m # bold, underlined, inverse
abcdef
\e[0m
\e[2*x
\e[1;1;1;3;0$r
|abcdef|
attr 1,1 plain
attr 1,3 plain
attr 1,4 bold underline inverse

DECCARA-4: The characters and the current rendition stay

abcdef
\e[2*x
\e[1;1;1;3;1$r
\e[1;4H
X         # written in the current rendition, still plain
|abcXef|
attr 1,1 bold
attr 1,4 plain

DECCARA-5: DECRARA reverses

\e[1mab\e[0mcd # ab bold, cd not
\e[2*x
\e[1;1;1;4;1$t
|abcd__|
attr 1,1 -bold
attr 1,2 -bold
attr 1,3 bold
attr 1,4 bold

DECCARA-6: A stream skips empty cells

ab
\e[1;1;1;6;7$r # inverse, as a stream
|ab____|
attr 1,2 inverse
attr 1,4 -inverse

DECCARA-7: A rectangle does not

ab
\e[2*x
\e[1;1;1;6;7$r # inverse, as a rectangle
|ab____|
attr 1,2 inverse
attr 1,4 inverse

DECCARA-8: Reading DECSACE back

\e[2*x
\eP$q*x\e\\ # DECRQSS for DECSACE
|______|
reply \eP1$r2*x\e\\
Every example on these pages runs in your browser, in libghostty-vt compiled to WebAssembly.