# Status Display (DECSASD, DECSSDT)

> Show a status line below the screen, and send text to it instead of the screen.

- **Sequence:** `CSI Ps $ }`
- **Defaults:** Ps = 0, the main display
- **DEC STD 070:** [§14.3 Select Active Status Display, p. 14-11](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n1046/mode/1up)
- **VT510:** [DECSASD—Select Active Status Display](https://vt100.net/docs/vt510-rm/DECSASD.html)

A DEC terminal can show a *status line* below the main display. DECSSDT,
`CSI Ps $ ~`, chooses what kind:

| `Ps` | Status line |
| --- | --- |
| `0`, or left out | none, the factory default |
| `1` | an *indicator* line, which the terminal fills in itself |
| `2` | a *host-writable* line, which the host program writes to |

DECSASD, `CSI Ps $ }`, then chooses where what the host sends goes: `0`
to the main display, `1` to a host-writable status line. DEC STD 070 defines
DECSSDT on
[p. 14-12](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n1047/mode/1up),
and the VT510 manual as
[DECSSDT—Select Status Display (Line) Type](https://vt100.net/docs/vt510-rm/DECSSDT.html).

A host-writable status line is a display of its own, one line high. DEC STD
070 says it keeps its own cursor position, rendition, origin mode,
character sets and saved cursor
([§14.2.2, p. 14-7](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n1042/mode/1up)),
and that while it is selected "any data received by the terminal is placed
into the Status Display, and most ANSI control functions received will
affect only the Status Display"
([§14.2.3, p. 14-8](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n1043/mode/1up)).
DECSASD can only select it once DECSSDT has made it host-writable: "the Host
Writable Status Line must be selected through DECSSDT for DECSASD to be able
to select the Host Writable Status Line". Choosing another status line type
with DECSSDT, DECSTR and RIS each send the host back to the main display.
The status line is an extension to level 2 and required at level 3.

xterm has both functions only when it is built with
`--enable-status-line`, which is off by default
([`configure.in`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/configure.in#L936-L942)).
Without it, its parse table turns both sequences into nothing
([`VTPrsTbl.c`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/VTPrsTbl.c#L122-L127)).
An xterm built with it implements both as DEC STD 070 describes, growing its
window by a line for the status line
([`update_status_line`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/charproc.c#L2913-L3005),
[`handle_DECSASD`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/charproc.c#L3015-L3045)).
A default xterm, then, ignores both, and the cases follow it, as the
[sources](https://control-codes.page/sources/index.html.md) page explains: text sent after `CSI 1 $ }` is written to
the main display as if the sequence had never come, and every control acts
there too. The case runner shows only the main display, which is all a
default xterm has.

## Not quite in libghostty-vt

libghostty-vt handles DECSASD, but not DECSSDT, and has no status line to
write to. While DECSASD has selected the status line, its `print` in
`Terminal.zig` returns without doing anything ("If we're not on the main
display, do nothing for now"), so text is discarded where a default xterm
would print it. Everything else still acts on the main display, as it does
in xterm: the cursor moves and erases erase there. Since DECSSDT does
nothing, DECSASD 1 discards text even when there is no host-writable status
line to select, and DECSSDT cannot send the host back to the main display.
RIS does return to the main display; DECSTR, which libghostty-vt does not
implement (see [DECSTR](https://control-codes.page/csi/decstr/index.html.md)), does not. Every case that prints
while `CSI 1 $ }` is in effect is therefore a known difference.

## Validation

### DECSASD-1: Selecting the status line is ignored

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

Input, one step per line:

```text
\e[1$}    # DEC STD 070: select the status line, but none is host-writable
AB
\e[0$}
C
```

Expected screen:

```text
|ABC__|
|_____|
```

### DECSASD-2: Text stays on the main display

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

Input, one step per line:

```text
\e[2$~    # DEC STD 070: a host-writable status line
\e[1$}    # DEC STD 070: select it
AB        # a default xterm prints this on the main display
\e[0$}
C
```

Expected screen:

```text
|ABC__|
|_____|
cursor 1,4
```

### DECSASD-3: Controls act on the main display

Input, one step per line:

```text
XY
\e[2$~
\e[1$}
\e[2J     # DEC STD 070: erases the status line instead
\e[0$}
```

Expected screen:

```text
|_____|
|_____|
```

### DECSASD-4: There is only the main display's cursor

Input, one step per line:

```text
XY
\e[2$~
\e[1$}
\e[1;5H   # DEC STD 070: moves the status line's cursor instead
\e[0$}
Z
```

Expected screen:

```text
|XY__Z|
|_____|
```

### DECSASD-5: After DECSSDT 0

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

Input, one step per line:

```text
\e[2$~
\e[1$}
\e[0$~    # DEC STD 070: no status line, so the status display is exited
AB
```

Expected screen:

```text
|AB___|
|_____|
```

### DECSASD-6: After RIS

Input, one step per line:

```text
\e[2$~
\e[1$}
\ec       # RIS
AB
```

Expected screen:

```text
|AB___|
|_____|
```

### DECSASD-7: After DECSTR

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

Input, one step per line:

```text
\e[2$~
\e[1$}
\e[!p     # DECSTR
AB
```

Expected screen:

```text
|AB___|
|_____|
```

---

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