DECSC / DECRC — Save and restore cursor
Push and pop the cursor state (position + attributes).
Byte forms
Every common string-literal form so you can paste-and-search either direction.
\x1b7 (save) \x1b8 (restore)\0337 / \0338\e7 / \e8ESC 7 / ESC 81b 37 / 1b 38Description
DECSC (ESC 7, hex 1b 37) and DECRC (ESC 8, hex 1b 38) are DEC-private 2-byte escapes — *not* CSI sequences. There is no leading \x1b[ and no parameter; the second byte is a literal ASCII 7 or 8 (not the control character 0x07 BEL). DECSC pushes the full cursor state onto a 1-deep terminal-side stack: position (row + column), the active SGR attributes (bold / italic / underline / fg / bg), the G0..G3 charset selections, the origin-mode flag (DECOM ?6), the wraparound flag (DECAWM ?7), and the cursor-visibility flag. DECRC pops it back. ECMA-48 calls these "SCS / RCS" in §8.3.79 and §8.3.80; the xterm-ctlseqs naming "DECSC / DECRC" is the de-facto standard. The stack depth is exactly 1 — a second DECSC overwrites the saved state, so this primitive cannot be used recursively across nested redraws.
The CSI siblings \x1b[s (SCOSC — save) and \x1b[u (SCORC — restore) date from the SCO console and historically saved *only* the cursor position, not the full attribute set; xterm and every modern emulator now treat the SCO and DEC pairs as equivalent, but screen 4.x, very old framebuffer Linux consoles, and a handful of Windows console emulators (pre-ConPTY 1809) still implement SCOSC / SCORC as position-only. The decsc-vs-scosc distinction matters when you draw with SGR colours inside a save / restore block and then expect attributes to be restored — on a position-only implementation the cursor jumps back but the SGR state is whatever was emitted most recently. Linux console / fbcon implements DECSC / DECRC; ConPTY 1809+ forwards it correctly; tmux passes it through within a pane (but the per-pane save state does not persist across tmux detach / attach). Inside the alt-screen (DECSET ?1049 or ?1047), most terminals maintain *separate* DECSC stacks for the normal and alt buffers — so a DECSC emitted on the primary buffer is not restorable from the alt buffer.
There is no separate "close" — DECSC / DECRC are a balanced pair. The portability rule for cross-emulator TUIs is *always* use DECSC / DECRC for the position+attribute pair you need restored after a draw, and use the explicit XTSAVE / XTRESTORE stack (\x1b[?Pn s / \x1b[?Pn r) for any DEC private mode (mouse, bracketed paste, cursor visibility) you also want to restore. Stacking multiple DECSC calls *does not nest*; if your TUI saves cursor → draws menu → user presses arrow → you save cursor again → user dismisses → you restore, the second DECSC has overwritten the first save and the cursor lands wrong. The fix is either to compose explicit absolute positioning with cursor-position (CUP) or to maintain the saved-state stack inside your application. Related: cursor-position (CUP — absolute placement, the alternative when 1-deep DEC stack isn't enough), cursor-move (CUU / CUD / CUF / CUB — relative moves that don't need a save / restore pair), sco-save-restore (the CSI sibling pair, position-only on legacy implementations).
Spec citation: DEC STD 070 / xterm-ctlseqs
Examples
printf '\0337move\033[5;5HHERE\0338back\n'print('\x1b7\x1b[5;5HHERE\x1b8')fmt.Print("\x1b7\x1b[5;5HHERE\x1b8")process.stdout.write('\x1b7\x1b[5;5HHERE\x1b8')printf("\x1b7\x1b[5;5HHERE\x1b8");Used in
Real-world tools that emit this sequence — anchors the bytes to commands you've already used.
- bash, zsh readlinearound prompt redraw so user input position is preserved
- npm, pnpm, yarn progress barssave → write progress line → restore so the next log line lands on a fresh row
- ora, cli-spinners (Node)
- tmux status-line updates
Frequently asked
Short answers to the questions developers actually search for this sequence.
- What's the difference between DECSC / DECRC and SCOSC / SCORC?
- DECSC (
\x1b7) / DECRC (\x1b8) save and restore cursor position plus the full graphic-rendition state (SGR attributes, character set, origin mode). SCOSC (\x1b[s) / SCORC (\x1b[u) save and restore *only* the cursor position. DECSC is the safer default for TUI snapshots; SCOSC is fine when you just need to bounce the cursor and don't care about restoring colour. Some terminals overload\x1b[sfor DECSLRM under DEC private mode 69 — DECSC sidesteps that ambiguity. - Can I nest DECSC / DECRC calls?
- No. DECSC keeps a single save slot per buffer (main + alternate each have their own). A second DECSC overwrites the first, so if you save → save → restore → restore, both restores recover the *second* save. For nested transient moves, manage your own stack: save the current row/col into program memory and call CUP (
\x1b[r;cH) to return.
Terminal support
- xterm
- yes
- Linux console (fbcon)
- yes
- macOS Terminal.app
- yes
- iTerm2
- yes
- Windows Terminal
- yes
- cmd.exe / ConPTY
- yes
- kitty
- yes
- alacritty
- yes
- WezTerm
- yes
- Ghostty
- yes
- GNOME Terminal
- yes
- Konsole
- yes
- tmux
- yes
- GNU screen
- yes
| xterm | Linux console (fbcon) | macOS Terminal.app | iTerm2 | Windows Terminal | cmd.exe / ConPTY | kitty | alacritty | WezTerm | Ghostty | GNOME Terminal | Konsole | tmux | GNU screen |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes |