DECNCSM —— 切列宽时不清屏(`CSI ? 95 h / l`)
抑制 DECCOLM(及 DECSCPP)切列宽时隐含的清屏副作用。DECNCSM 开启后,在 80 / 132 列之间切换会保留单元内容,而非清空。
字节形式
涵盖所有常见的字符串字面量写法,方便正反查找。
\x1b[?95h (set — preserve) \x1b[?95l (reset — clear)\033[?95h\e[?95hESC [ ? 9 5 h / ESC [ ? 9 5 l1b 5b 3f 39 35 68 / 6c说明
DECNCSM —— *切列宽时不清屏* —— 是控制 deccolm(DEC 132 列模式,?3h/l)与 decscpp(每页列数选择,CSI Pn $|)「切宽即清屏」副作用的修饰模式。
关闭(默认,\x1b[?95l) —— DECCOLM 与 DECSCPP 按历史规范运作:切 80 / 132 列时清屏、光标归位、DECSTBM 滚动区重置全屏、DECSLRM 左右边距重置。这是 VT100 硬件原始行为 —— CRT 无法重排文本,屏幕被擦掉。
开启(\x1b[?95h) —— DECCOLM / DECSCPP 保留单元内容。新宽度外的单元被丢弃(或部分实现下隐藏到切回更宽列时再现)。DECSTBM 与 DECSLRM 仍重置;光标按新几何重定位。这是现代终端模拟器对希望「拉宽 / 缩窄不丢上下文」用户更友好的默认。
为何存在 —— 需要历史 DECCOLM 行为(如 xterm 在 allowC132 模式下做 VT220 一致性测试)的程序必须清;想做响应式缩放(「用户切宽时保留缓冲」浏览器式语义)的现代程序则要保留。DECNCSM 把选择权交给应用代码。部分用户在 xterm 资源里永久打开(*decTerminalID: vt320 + *setColumnRequired: false),让缩放体验更顺。
与 deccolm / decscpp 的交互:
- \x1b[?95l + \x1b[?3h → 切到 132 列,清屏(历史)。
- \x1b[?95h + \x1b[?3h → 切到 132 列,保留内容。
- 同样适用于 \x1b[80$| / \x1b[132$|(DECSCPP)。
重要的非作用:DECNCSM 只抑制 *DECCOLM / DECSCPP 引起的清屏*。RIS(\x1bc)、DECSTR(\x1b[!p,见 decstr-side-effects)、显式 ED(\x1b[2J)仍照清不误。别把 DECNCSM 当通用「别清屏」开关 —— 它只作用于列宽切换。
覆盖度:xterm = 完整(标准实现)。Kitty / WezTerm / Ghostty = 完整。iTerm2 = 完整。Konsole = 完整。Windows Terminal = 部分(DECCOLM 本身受配置控制,启用后 1.18+ 起 DECNCSM 起效)。Alacritty = 实际无作用(DECCOLM 自身就是 no-op,DECNCSM 无东西可门控)。Linux console / macOS Terminal / cmd / ConPTY / gnome-terminal = 无作用。
查询:\x1b[?95$p(DECRQM,见 decrqm / decrpm-decoder)—— 设置时回 \x1b[?95;1$y,重置时回 \x1b[?95;2$y。
规范出处: DEC VT510 RM (DECNCSM) / xterm-ctlseqs (CSI ? 95 h / l)
示例
# Enable preserve-on-resize, then switch to 132 columns without losing buffer.\nprintf '\\033[?95h' # DECNCSM set — no clear on column-mode change\nprintf '\\033[?3h' # DECCOLM 132 col (with DECNCSM, contents survive)import sys\nsys.stdout.write('\\x1b[?95h') # don't clear on column toggle\nsys.stdout.write('\\x1b[132$|') # DECSCPP to 132 cols, preserving buffer\nsys.stdout.flush()// Persist DECNCSM at startup, restore at exit.\nfmt.Print(\"\\x1b[?95s\") // XTSAVE — push current value\nfmt.Print(\"\\x1b[?95h\") // enable preserve\ndefer fmt.Print(\"\\x1b[?95r\") // XTRESTORE on exit// Probe DECNCSM state before deciding whether to defensively redraw on resize.\nprocess.stdout.write('\\x1b[?95$p');\n// expect reply \\x1b[?95;1$y (set) or ?95;2$y (reset)/* Disable preserve (restore historical clear-on-DECCOLM). */\nprintf(\"\\x1b[?95l\");终端支持
- xterm
- 支持
- Linux console (fbcon)
- 不支持
- macOS Terminal.app
- 不支持
- iTerm2
- 支持
- Windows Terminal
- 部分
- cmd.exe / ConPTY
- 不支持
- kitty
- 支持
- alacritty
- 不支持
- WezTerm
- 支持
- Ghostty
- 支持
- GNOME Terminal
- 不支持
- Konsole
- 支持
- tmux
- 支持
- GNU screen
- 支持
| xterm | Linux console (fbcon) | macOS Terminal.app | iTerm2 | Windows Terminal | cmd.exe / ConPTY | kitty | alacritty | WezTerm | Ghostty | GNOME Terminal | Konsole | tmux | GNU screen |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 支持 | 不支持 | 不支持 | 支持 | 部分 | 不支持 | 支持 | 不支持 | 支持 | 支持 | 不支持 | 支持 | 支持 | 支持 |