# Change Attributes in Rectangular Area (DECCARA)

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

- **Sequence:** `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](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n427/mode/1up)
- **VT510:** [DECCARA—Change Attributes in Rectangular Area](https://vt100.net/docs/vt510-rm/DECCARA.html)

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

| Sequence | Function | Does |
| --- | --- | --- |
| `CSI Pt ; Pl ; Pb ; Pr ; Pm $ r` | DECCARA | sets or clears attributes |
| `CSI Pt ; Pl ; Pb ; Pr ; Pm $ t` | DECRARA | reverses attributes: turns each one on where it is off, and off where it is on |
| `CSI Ps * x` | DECSACE | chooses which cells the other two change |

The first four parameters are a rectangle's corners, as for
[DECERA](https://control-codes.page/csi/decera/index.html.md): left out or `0` they take the screen's edge, and only
[origin mode](https://control-codes.page/modes/decom/index.html.md) brings the margins into it. The rest are
[SGR](https://control-codes.page/csi/sgr/index.html.md) 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](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n429/mode/1up)
and DECSACE at [p. 5-177](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n431/mode/1up);
the VT510 manual has [DECRARA](https://vt100.net/docs/vt510-rm/DECRARA.html)
and [DECSACE](https://vt100.net/docs/vt510-rm/DECSACE.html).

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`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/screen.c#L2959-L3085),
following DEC STD 070, and a host can read the setting back with
[DECRQSS](https://control-codes.page/esc/dcs/index.html.md).

## Not in libghostty-vt

These are VT420 rectangle operations, level 4 in DEC STD 070. libghostty-vt,
a VT220 (see [DA](https://control-codes.page/csi/da/index.html.md)), 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`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/charproc.c#L5695-L5717)),
so every case below expects xterm's result and is a known difference (see
the [sources](https://control-codes.page/sources/index.html.md) page).

## Validation

### DECCARA-1: Bold, in a rectangle

*A known difference: libghostty-vt does not pass this case.*

Input, one step per line:

```text
abcdef\r\nghijkl\r\nmnopqr
\e[2*x    # DECSACE: rectangle
\e[1;2;2;4;1$r
```

Expected screen:

```text
|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

*A known difference: libghostty-vt does not pass this case.*

Input, one step per line:

```text
abcdef\r\nghijkl\r\nmnopqr
\e[1;2;2;4;1$r # DECSACE is a stream by default
```

Expected screen:

```text
|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

*A known difference: libghostty-vt does not pass this case.*

Input, one step per line:

```text
\e[1;4;7m # bold, underlined, inverse
abcdef
\e[0m
\e[2*x
\e[1;1;1;3;0$r
```

Expected screen:

```text
|abcdef|
attr 1,1 plain
attr 1,3 plain
attr 1,4 bold underline inverse
```

### DECCARA-4: The characters and the current rendition stay

*A known difference: libghostty-vt does not pass this case.*

Input, one step per line:

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

Expected screen:

```text
|abcXef|
attr 1,1 bold
attr 1,4 plain
```

### DECCARA-5: DECRARA reverses

*A known difference: libghostty-vt does not pass this case.*

Input, one step per line:

```text
\e[1mab\e[0mcd # ab bold, cd not
\e[2*x
\e[1;1;1;4;1$t
```

Expected screen:

```text
|abcd__|
attr 1,1 -bold
attr 1,2 -bold
attr 1,3 bold
attr 1,4 bold
```

### DECCARA-6: A stream skips empty cells

*A known difference: libghostty-vt does not pass this case.*

Input, one step per line:

```text
ab
\e[1;1;1;6;7$r # inverse, as a stream
```

Expected screen:

```text
|ab____|
attr 1,2 inverse
attr 1,4 -inverse
```

### DECCARA-7: A rectangle does not

*A known difference: libghostty-vt does not pass this case.*

Input, one step per line:

```text
ab
\e[2*x
\e[1;1;1;6;7$r # inverse, as a rectangle
```

Expected screen:

```text
|ab____|
attr 1,2 inverse
attr 1,4 inverse
```

### DECCARA-8: Reading DECSACE back

*A known difference: libghostty-vt does not pass this case.*

Input, one step per line:

```text
\e[2*x
\eP$q*x\e\\ # DECRQSS for DECSACE
```

Expected screen:

```text
|______|
reply \eP1$r2*x\e\\
```

---

This is the Markdown version of <https://control-codes.page/csi/deccara/>. On that page every validation case runs live in libghostty-vt, the terminal emulation core of Ghostty, compiled to WebAssembly.

The validation cases are written in the notation described in <https://control-codes.page/notation/index.html.md>.
