# Save and Restore Cursor (DECSC, DECRC)

> Save the cursor and its attributes, and later put them back.

- **Sequence:** `ESC 7`
- **DEC STD 070:** [§5.13.1 Save Cursor, p. 5-187](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n441/mode/1up)
- **VT510:** [DECSC—Save Cursor](https://vt100.net/docs/vt510-rm/DECSC.html)

`ESC 7` (DECSC) saves the state of the cursor, and `ESC 8` (DECRC) puts it
back. DEC STD 070 lists what is saved, and it is more than the position:

- the cursor position,
- the character attributes set by [SGR](https://control-codes.page/csi/sgr/index.html.md),
- origin mode (DECOM),
- the character sets designated as G0 through G3, and which of them is
  invoked into GL (and, from level 2, GR),
- the selective erase attribute (DECSCA), where it is supported.

The VT510 manual's list also has a "wrap flag (autowrap or no autowrap)".
DEC STD 070 leaves it out of DECSC's own definition, but its appendix on
autowrap says the pending wrap, which it calls the *Last Column Flag*,
"should be saved when a Save Cursor operation is performed, and restored
when a Restore Cursor operation is performed"
([§D.6.1, p. D-14](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n1200/mode/1up)). xterm saves the pending wrap along with
the rest, in [`CursorSave2`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/cursor.c#L398-L416), and puts it back last of
all, in [`CursorRestoreFlags`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/cursor.c#L467-L494). It also keeps a saved
cursor for each of the main and alternate screens, so a program on the
alternate screen does not disturb what was saved on the main one.

There is only one saved cursor, so saving again replaces it. Restoring when
nothing has been saved puts the cursor at the top-left with default
attributes, because the save buffer starts out holding exactly that.

DECRC is defined in
[DEC STD 070 §5.13.1, p. 5-189](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n443/mode/1up)
and in the VT510 manual as
[DECRC—Restore Cursor](https://vt100.net/docs/vt510-rm/DECRC.html).

`CSI s` and `CSI u` are often used for the same thing, but `CSI s` means
something else (DECSLRM) once left and right margins are enabled.

## Validation

### DECSC-1: Position

Input, one step per line:

```text
\e[2;3H
\e7       # save
\e[1;1H
A
\e8       # restore
B
```

Expected screen:

```text
|A____|
|__B__|
```

### DECSC-2: Attributes

Input, one step per line:

```text
\e[1;31m  # bold red
\e7       # save
\e[0m
A
\e8       # restore
B
```

Expected screen:

```text
|B____|
attr 1,1 bold fg=1
```

### DECSC-3: Nothing saved

Input, one step per line:

```text
\e[1m
\e[2;4H
\e8       # restore, with nothing saved
A
```

Expected screen:

```text
|A____|
|_____|
attr 1,1 plain
```

---

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