Skip to main content
ansicode

DECSACE — Select Attribute Change Extent (`CSI Ps * x`)

Toggle whether DECCARA / DECRARA treat their rectangle as a literal cell block (default) or as a stream from start-position to end-position. The content-side rect ops (DECCRA / DECFRA / DECERA / DECSERA) are unaffected.

Byte forms

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

\\x1b[\x1b[<Ps>*x
\\033[\033[0*x / \033[1*x / \033[2*x
\\e[\e[0*x / \e[1*x / \e[2*x
ESC [ESC [ Ps * x
hex1b 5b 30 2a 78 / 1b 5b 31 2a 78 / 1b 5b 32 2a 78

Description

**DECSACE** is the one-byte parameter that decides what 'a rectangle' means to **DECCARA** (`$r`) and **DECRARA** (`$t`). The content-side ops — **DECCRA** (`$v`), **DECFRA** (`$x`), **DECERA** (`$z`), **DECSERA** (`${`) — always use block semantics regardless of DECSACE (see `dec-rect-ops`). **Parameters** - `Ps = 0` (default) or `Ps = 1` — **block / rectangle** mode. Coordinates name the corners of a strict cell rectangle. `Pt;Pl` is the top-left, `Pb;Pr` is the bottom-right; the affected cells form a literal rectangle of `(Pb−Pt+1) × (Pr−Pl+1)` cells. - `Ps = 2` — **stream** mode. Coordinates name two positions in text-flow order. `Pt;Pl` is the stream-start, `Pb;Pr` is the stream-end; the affected cells are every cell on or after start through the end, following normal text wrap. A 'paragraph' highlighter — e.g. bold the prose from `(3,1)` through `(7,40)` ignoring column boundaries. **Query**: DECSACE is reported via DECRQM with private mode `?92` (`\x1b[?92$p` reply: `\x1b[?92;<Ps>$y` where `Ps` is the active extent — `2` means stream, anything else means block). Some emulators report `1` for the default rather than `0`. **Persistence**: the value is part of terminal state — saved by DECRQTSR / DECSC and restored by DECRSTS / DECRC. DECSTR (soft reset) resets DECSACE to block (`Ps = 0`). RIS (hard reset) does the same. **Practical use**: the **block** default is what TUIs and screen renderers want — a rectangle attribute change is a rectangle. **Stream** mode is what *editors* want when re-attributing a selection that may span line wraps without preserving column structure — VS Code-style 'underline this prose span'. The mode is sticky, so toggle to stream, do the rect-attr ops, toggle back to block. Don't leave it in stream mode — later code that assumes block semantics will mis-paint. **Coverage**: **xterm** = full (definitive). **Konsole** + **gnome-terminal** + **mlterm** + **WezTerm** + **Ghostty** = full. **iTerm2** = partial (DECRQM `?92` reports correctly, but stream-mode DECRARA mis-paints when the rectangle straddles a wrapped line). **Kitty** = partial (mode is parsed and stored, but DECCARA / DECRARA themselves are partial — see their entry). **Alacritty** + **Windows Terminal** + **cmd / ConPTY** + **Linux console** + **macOS Terminal** = no-op (DECCARA / DECRARA also no-op, so DECSACE has nothing to switch).

Spec citation: DEC VT510 RM (DECSACE) / xterm-ctlseqs (CSI Ps * x)

Parameters

Ps = 0 or 1Block (rectangle) mode — DECCARA / DECRARA treat coords as rect corners. Default.
Ps = 2Stream mode — DECCARA / DECRARA treat coords as start / end positions in text flow.

Examples

bash
# Enter stream mode, bold a prose span from (3,1) to (7,40), restore block.\nprintf '\\033[2*x'                  # DECSACE = stream\nprintf '\\033[3;1;7;40;1$r'         # DECCARA bold\nprintf '\\033[0*x'                  # DECSACE = block (cleanup)
python
import sys\nsys.stdout.write('\\x1b[?92$p')   # DECRQM probe — what's the current extent?\nsys.stdout.flush()\n# Reply on stdin: '\\x1b[?92;0$y' = block, ';2$y' = stream.
go
// Always restore block mode before exiting a TUI subroutine.\ndefer fmt.Print(\"\\x1b[0*x\")\nfmt.Print(\"\\x1b[2*x\")  // stream for the duration\n// ... rect-attr work ...
javascript
// Highlight a wrap-aware selection: positions 12,5 -> 18,40 as one stream.\nprocess.stdout.write('\\x1b[2*x\\x1b[12;5;18;40;7$r\\x1b[0*x');
c
/* Toggle stream mode briefly; assume xterm or konsole. */\nprintf(\"\\x1b[2*x\");\nprintf(\"\\x1b[%d;%d;%d;%d;1;4$r\", t, l, b, r);  /* bold + underline */\nprintf(\"\\x1b[0*x\");

Terminal support

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

Related sequences