Skip to main content
ansicode

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.

\\x1b[\x1b7 (save) \x1b8 (restore)
\\033[\0337 / \0338
\\e[\e7 / \e8
ESC [ESC 7 / ESC 8
hex1b 37 / 1b 38

Description

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

bash
printf '\0337move\033[5;5HHERE\0338back\n'
python
print('\x1b7\x1b[5;5HHERE\x1b8')
go
fmt.Print("\x1b7\x1b[5;5HHERE\x1b8")
javascript
process.stdout.write('\x1b7\x1b[5;5HHERE\x1b8')
c
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[s for 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

Related sequences