# Start and End of Guarded Area (SPA, EPA)

> Mark the characters written in between as protected from erasure.

- **Sequence:** `ESC V`
- **ECMA-48:** [§8.3.129 SPA – Start of Guarded Area, p. 66](https://archive.org/details/ecma-48-5th-edition-june-1991/page/n79/mode/1up)
- **xterm:** [C1 (8-Bit) Control Characters](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html)

`ESC V` (SPA) starts a *guarded area*, and `ESC W` (EPA,
[ECMA-48 §8.3.46, p. 43](https://archive.org/details/ecma-48-5th-edition-june-1991/page/n56/mode/1up))
ends it. The characters written between them are guarded. ECMA-48 defines a
guarded area as a protected one
([§6.5.2.2, p. 19](https://archive.org/details/ecma-48-5th-edition-june-1991/page/n32/mode/1up)):
its contents are protected against "manual alteration", that is, from the
keyboard, and may be protected against erasure, depending on the erasure
mode, ERM. ERM's reset state, which is the default, is PROTECT: "Only the
contents of unprotected areas are affected by an erasure control function",
meaning [EL](https://control-codes.page/csi/el/index.html.md), [ED](https://control-codes.page/csi/ed/index.html.md) and [ECH](https://control-codes.page/csi/ech/index.html.md)
([§7.2.4, p. 22](https://archive.org/details/ecma-48-5th-edition-june-1991/page/n35/mode/1up)).

So in practice a guarded character survives erasing. It is not protected
from anything else: a character written over it replaces it, and
[DCH](https://control-codes.page/csi/dch/index.html.md), which deletes rather than erases, moves it along with the
rest of the line.

**DECSCA** (`CSI Ps " q`) is DEC's own way of protecting characters
([DEC STD 070 §5.11.1, p. 5-166](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n420/mode/1up),
[VT510 DECSCA](https://vt100.net/docs/vt510-rm/DECSCA.html)), and it works
the other way round. A character protected with DECSCA survives only the
*selective* erases, DECSEL (`CSI ? K`) and DECSED (`CSI ? J`), and is erased
by EL and ED like any other. xterm keeps the two kinds apart: SPA sets its
ISO protection
([`CASE_SPA`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/charproc.c#L5367-L5378)),
which every erase respects, while for DEC protection an ordinary erase
switches protection off for its duration
([`do_erase_line`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/util.c#L2406-L2429)).
libghostty-vt does the same.

SPA and EPA are C1 controls, with single-byte forms `96` and `97` that
libghostty-vt, decoding its input as UTF-8, does not accept. Neither DEC STD
070 nor the VT510 manual defines them.

## Validation

### SPA-1: EL does not erase a guarded area

Input, one step per line:

```text
AB
\eV       # start of guarded area
CD
\eW       # end of guarded area
EF
\e[1;1H
\e[K
```

Expected screen:

```text
|__CD__|
```

### SPA-2: Nor does ED

Input, one step per line:

```text
AB\eVCD\eWEF
\e[2J
```

Expected screen:

```text
|__CD__|
|______|
```

### SPA-3: Nor does ECH

Input, one step per line:

```text
AB\eVCD\eWEF
\e[1;1H
\e[6X
```

Expected screen:

```text
|__CD__|
```

### SPA-4: Writing over it is allowed

Input, one step per line:

```text
AB\eVCD\eWEF
\e[1;3H
XY
```

Expected screen:

```text
|ABXYEF|
```

### SPA-5: Deleting is not erasing

Input, one step per line:

```text
AB\eVCD\eWEF
\e[1;1H
\e[P      # DCH
```

Expected screen:

```text
|BCDEF_|
```

### SPA-6: DECSCA protection does not stop EL

Input, one step per line:

```text
AB
\e[1"q    # DECSCA: protected
CD
\e[0"q    # DECSCA: not protected
EF
\e[1;1H
\e[K
```

Expected screen:

```text
|______|
```

### SPA-7: It stops a selective erase

Input, one step per line:

```text
AB\e[1"qCD\e[0"qEF
\e[1;1H
\e[?K     # DECSEL
```

Expected screen:

```text
|__CD__|
```

---

This is the Markdown version of <https://control-codes.page/esc/spa/>. 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>.
