跳到主要内容
ansicode

DECDMAC / DECINVM — 定义与调用宏(DCS Pn ; Pn ; Pn ! z ... ST / CSI Pn * z)

用数字句柄存储一段字节序列(DECDMAC),按需回放(DECINVM)—— DEC VT520 的终端内置宏录制器。

字节形式

涵盖所有常见的字符串字面量写法,方便正反查找。

\\x1b[\x1bP<Pid>;<Pdt>;<Penc>!z<MACRO-BODY>\x1b\\ (define) \x1b[<Pid>*z (invoke)
\\033[\033P<Pid>;<Pdt>;<Penc>!z<body>\033\\ / \033[<Pid>*z
\\e[\eP<Pid>;<Pdt>;<Penc>!z<body>\e\\ / \e[<Pid>*z
ESC [ESC P Pid ; Pdt ; Penc ! z BODY ESC \ / ESC [ Pid * z
hex1b 50 ... 21 7a ... 1b 5c / 1b 5b ... 2a 7a

说明

DEC VT520 / VT525 宏机制 —— 一对组合序列。**DECDMAC**(定义宏)是中间字节 `!`(0x21)、末字节 `z`(0x7a)的 DCS 帧,把体 `<MACRO-BODY>` 存于整数句柄 `Pid`(0–63)下。参数: - `Pid` —— 宏编号(0–63)。 - `Pdt`(delete-type)—— `0`(默认)只覆盖本宏;`1` 在写入前删除**所有**宏。 - `Penc`(encoding)—— `0`(默认)体为普通 7 / 8 位终端字节;`1` 体为十六进制编码(每两个十六进制 = 一字节)—— 十六进制形式让宏可安全包含 ESC、ST、`;` 等会提前终止 DCS 帧的解析敏感字节。 **DECINVM**(调用宏)是中间字节 `*`(0x2a)、末字节 `z` 的 CSI 序列 —— `\x1b[<Pid>*z` 回放该句柄下存储的全部字节,仿佛它们是刚通过线路到达(任何嵌入的 SGR、光标移动、OSC 等都以正常解析器状态执行)。 **用途**(历史):表单录入终端 —— 主机程序在会话开始时定义一组稳定的光标定位 + 框线宏,随后用短小的 DECINVM 调用驱动屏幕,而非在整页里重复发送沉重的 CSI 序列上千次。在慢串口上省字节(原始动机);同时让终端缓存光标定位工作。 **现代相关性**:基本为零。仅 xterm 以有意义的精度实现两者(`disallowedColors` / `allowMacro` 资源默认**关**,因远程进程定义后被调用的宏是一个小但真实的 shell 集成 / 剪贴板注入攻击面)。现代模拟器(alacritty / kitty / wezterm / ghostty / Windows Terminal)静默忽略两者。用途:VT520 忠实模拟器测试套件、表单终端保留工作、奇异演示。

规范出处: DEC VT520 RM (DECDMAC / DECINVM) / xterm-ctlseqs

参数

Pid宏编号 0–63(定义与调用共享同一数字命名空间)。
PdtDECDMAC 的删除类型:0 = 仅覆盖该槽,1 = 先删除所有宏。
PencDECDMAC 体的编码:0 = 原始字节,1 = 十六进制编码(对 ESC / ST / `;` 安全)。

示例

bash
# Define macro 1 = 'cursor-home + clear screen', then invoke twice.\nprintf '\033P1;0;0!z\033[H\033[2J\033\\\\'\nprintf '\033[1*z'   # invoke — clears screen\nprintf '\033[1*z'   # invoke again — still clears
python
import sys\n# Hex-encoded body so the macro can contain ESC safely:\nbody_hex = '1b5b481b5b324a'           # ESC[H ESC[2J\nsys.stdout.write(f'\x1bP2;0;1!z{body_hex}\x1b\\\\')\nsys.stdout.write('\x1b[2*z')   # invoke macro 2
go
// Define a 'red bold' SGR macro then invoke at every log line:\nfmt.Print("\x1bP3;0;0!z\x1b[1;31m\x1b\\\\")\nfor _, line := range lines { fmt.Print("\x1b[3*z" + line + "\x1b[0m\n") }
javascript
// Wipe all macros and store a fresh one in slot 0:\nprocess.stdout.write('\x1bP0;1;0!zHELLO\x1b\\\\')\nprocess.stdout.write('\x1b[0*z')   // prints HELLO
c
/* Define macro 7 = SGR reset; invoke at end of every styled span. */\nprintf("\x1bP7;0;0!z\x1b[0m\x1b\\\\");\nfor (int i = 0; i < n; ++i) {\n    print_colored(items[i]);\n    printf("\x1b[7*z");\n}

终端支持

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

相关序列

在家族食谱中

DCS 食谱 · 5. 有状态保存 / 重放 —— DECDMAC(定义宏)与 DECRSPS(恢复表现态)