Skip to main content
ansicode

DECRQTSR / DECRSTS — Request / Restore Terminal State Report

Save (CSI Ps$u → DCS reply) and restore (DCS Ps$p…ST) the whole DEC terminal state — the terminal-wide complement to dcs-decrsps' presentation-state-only scope.

Byte forms

Every common string-literal form so you can paste-and-search either direction.

\\x1b[\x1b[Ps$u request \x1bP<Ps>$p<body>\x1b\\ restore
\\033[\033[Ps$u request \033P<Ps>$p<body>\033\\ restore
\\e[\e[Ps$u request \eP<Ps>$p<body>\e\\ restore
ESC [ESC [ <Ps> $ u / ESC P <Ps> $ p <body> ESC \\
hex1b 5b … 24 75 / 1b 50 <Ps> 24 70 <body> 1b 5c

Description

DECRQTSR (*Request Terminal State Report*, \x1b[<Ps>$u) and its inverse DECRSTS (*Restore Terminal State*, \x1bP<Ps>$p<body>\x1b\\) bracket the DEC mechanism for snapshotting an *entire terminal*'s mutable state into an opaque blob and faithfully restoring it later. They are the terminal-wide counterpart to dcs-decrsps / dcs-decrqss, which only carry the *presentation* slice (cursor, SGR, charset, origin, tab stops).

Request\x1b[<Ps>$u. Ps=1 (the only universally-supported value) selects DEC terminal-state. Some VT-series docs reserve Ps=2 for color-table state, but no shipping emulator implements Ps=2 distinctly from Ps=1 — treat 1 as the only portable selector.

Reply (DECTSR)\x1bP<Ps>$s<body>\x1b\\. The $s intermediate-final distinguishes the DECTSR reply from the DECRSTS *restore* shape ($p) and from DECRPSS ($r). The <body> is opaque to the host — it's a serialised DEC-private snapshot of: tab stops, character set state (G0/G1/G2/G3 designators + GL/GR + UPSS), all mode states (DECCKM / DECANM / DECCOLM / DECSCLM / DECSCNM / DECOM / DECAWM / DECARM / DECTCEM / DECNRCM / DECSCA / DECNKM / DECSCUSR / DECSDM / DECSLRM), printer state, keyboard-mode state, current SGR pen, cursor position + save stack, and protected-area state. Hosts must not parse the body — semantics are reserved to the originating terminal.

Restore\x1bP<Ps>$p<body>\x1b\\. Pass the same <body> back verbatim. The terminal validates that <Ps> matches the saved blob's <Ps> (cross-Ps restore is rejected silently with \x1bP0$r\x1b\\ on emulators that reply, or simple no-op otherwise). Cross-terminal restore (saving on xterm, restoring on Konsole) is not portable — the body format is DEC-implementation-defined and each emulator has its own encoding.

Round-trip pattern (TUI takeover + restore): ``` startup: write '\x1b[1$u' # DECRQTSR Ps=1 read DCS until ST # reply '\x1bP1$s<body>\x1b\\' save body exit: write '\x1bP1$p' + body + '\x1b\\' ``` The modern reality: most TUIs use alt-screen (\x1b[?1049h/l) + DECSC/DECRC for cursor/SGR. DECRQTSR/DECRSTS is the terminal-wide option only when alt-screen is unavailable (some BBS / serial-multiplexer paths) or when you need to round-trip modes that DECSTR doesn't touch (NRCS, UPSS, DECSCA).

Edge cases - Reply uses \x1b\\ (ST as ESC + backslash) by default; xterm in 8-bit C1 mode (decscl-compat-level) uses single-byte \x9c — be prepared to terminate on either. - Body bytes can include \x1b followed by anything except \\ (DEC encodes embedded controls via DECDLD-style hex escapes); a naive 'split on ESC' parser will mis-frame — read until ST seen at packet boundary, not first ESC. - Some emulators (Linux console) reply with an empty body — restore is a silent no-op. - DECSTR (soft reset) does not clear an in-flight DECTSR snapshot held by the host, only the live terminal state.

Coveragexterm = full (reference; body length ~100-200 bytes typical). mlterm = full. WezTerm = partial (replies with a minimal body, restore accepts but only restores SGR + cursor + tabs — the modes DECSTR would reset get re-applied, the rest silently dropped). Konsole + gnome-terminal = partial (reply lacks UPSS / DECSCA fields, restore likewise truncated). Kitty + iTerm2 + Alacritty + Ghostty + Windows Terminal + cmd / ConPTY + macOS Terminal + Linux console = no-op (no reply at all — prefer alt-screen + cursor-save-restore + dcs-decrqss for round-trip on these).

Spec citation: DEC VT510 RM (DECRQTSR / DECTSR / DECRSTS) / xterm-ctlseqs (CSI Ps $ u)

Parameters

Ps = 1DEC terminal state. The only universally-supported value.
Ps = 2Reserved (color tables in some specs); no shipping emulator distinguishes from Ps=1.
Reply $s vs Restore $pDCS intermediate-final $s = report (terminal → host); $p = restore (host → terminal). Don't swap.
<body>Opaque DEC-private serialisation. Round-trip verbatim. Format varies per emulator — not cross-terminal portable.

Examples

bash
# Capture full terminal state, then restore on exit (xterm).\nprintf '\\033[1$u'\nIFS= read -rs -d '\\\\' -t 0.2 snapshot </dev/tty 2>/dev/null\n# ... session runs, mutates modes ...\n# Restore: re-emit the body in DECRSTS shape.\nbody=\"${snapshot#*\\\$s}\"\nbody=\"${body%\\\\}\"\nprintf '\\033P1$p%s\\033\\\\' \"$body\"
python
import sys, re\n# Save snapshot, then later push it back.\nsys.stdout.write('\\x1b[1$u'); sys.stdout.flush()\nreply = sys.stdin.buffer.read1(4096)\nm = re.search(rb'\\x1bP1\\$s(.*?)\\x1b\\\\', reply, re.DOTALL)\nbody = m.group(1) if m else b''\n# ... TUI session ...\nsys.stdout.flush()\nsys.stdout.buffer.write(b'\\x1bP1$p' + body + b'\\x1b\\\\')
go
// Skeleton: probe, read until ST, persist body for the duration of the run.\nfmt.Print(\"\\x1b[1$u\")\nvar buf [4096]byte\nn, _ := os.Stdin.Read(buf[:])\n// Match \\x1bP1$s<body>\\x1b\\\\.\nbody := extractDECTSR(buf[:n])\n// ...\nfmt.Printf(\"\\x1bP1$p%s\\x1b\\\\\", body)
javascript
// Snapshot at startup, restore on exit handler.\nprocess.stdout.write('\\x1b[1$u');\nlet snapshot = '';\nprocess.stdin.once('data', (buf) => {\n  const m = /\\x1bP1\\$s(.*?)\\x1b\\\\/s.exec(buf.toString('binary'));\n  if (m) snapshot = m[1];\n});\nprocess.on('exit', () => {\n  if (snapshot) process.stdout.write('\\x1bP1$p' + snapshot + '\\x1b\\\\');\n});
c
/* Skeleton: snapshot at TUI entry, restore at exit. */\nfputs(\"\\x1b[1$u\", stdout); fflush(stdout);\n/* read until ST seen at packet boundary, store body bytes opaquely. */\n/* on exit: fputs(\"\\x1bP1$p\", stdout); fwrite(body, 1, body_len, stdout); fputs(\"\\x1b\\\\\", stdout); */

Terminal support

xterm
yes
Linux console (fbcon)
no
macOS Terminal.app
no
iTerm2
no
Windows Terminal
no
cmd.exe / ConPTY
no
kitty
no
alacritty
no
WezTerm
partial
Ghostty
no
GNOME Terminal
partial
Konsole
partial
tmux
yes
GNU screen
yes

Related sequences

In the family cookbook

DCS cookbook · 3. Asking the terminal questions — DECRQSS, terminfo cap, DECRQTSR, DECRQUPSS, cursor-style