跳到主要内容
ansicode
CSI(光标与擦除)

CSI 转义码 —— 光标、擦除、滚动、定位

Control Sequence Introducer。`ESC [` 家族中扣除 SGR 子集后剩余的部分 —— 光标移动(上 / 下 / 左 / 右 / 列 / 绝对定位)、擦除(行 / 屏)、滚动、保存 / 恢复,以及少量用于窗口与光标状态查询的 CSI 序列。

60 条序列

CSI 食谱 —— 整族六大用途

CSI(Control Sequence Introducer)是转义码方言里最活跃的一族 —— 60 多个结尾字节几乎覆盖除了调色板 + 外壳之外的所有动作(那两类归 SGR 与 OSC)。下面六步:先认信封语法本身、再是光标移动、屏幕 / 行擦除、终端通过 stdin 回复的往返查询、TUI 划出固定区域用的滚动区与边距设置,最后是省去整屏重绘开销的局部插入 / 删除 / 光标形状操作。

  1. 1. 信封 —— \x1b[ …… <结尾字节>

    每条 CSI 序列都是 \x1b[(ESC [)起头,紧接可选的**私有前缀**(DEC 私有模式用 ?,xterm 定义的变种用 < / = / >),随后是零个或多个用 ; 分隔的数字参数,最后一个 \x40\x7E 范围的**结尾字节**决定动作。和 OSC 不同,CSI 不需要结束符 —— 结尾字节自己就是结束。SGR 用 m\x1b[31m),ED 用 J,EL 用 K,CUP(光标定位)用 H,DSR 用 n,DA 用 c —— ECMA-48 + xterm 加起来有 60 多个在用的结尾字节。参数会按动作默认成 1 或 0;省略等价于默认值,所以 \x1b[A(上移一行)和 \x1b[1A 完全等价。还有个 8-bit CSI 形式 \x9b …,老 VT 手册里能见到,实战里基本绝迹。

  2. 2. 光标移动 —— CUU / CUD / CUF / CUB + CUP + CHA / VPA

    撑起每个 TUI 的八条光标原语。**CUU / CUD / CUF / CUB**(\x1b[NA / B / C / D)让光标上 / 下 / 前 / 后移 N 格(默认 1),不会越出屏幕边界。**CUP**(\x1b[r;cH,别名 f)直接跳到行 rc(从 1 开始计)。**CHA**(\x1b[NG)和 **VPA**(\x1b[Nd)跳到绝对列 / 绝对行,另一轴保持不动。**CNL / CPL**(\x1b[NE / F)向下 / 向上 N 行的同时把列重置到 1 —— 适合段落式光标流。**SCOSC / SCORC**(\x1b[s / \x1b[u)保存 / 恢复一个光标槽位 —— 比 DECSC \x1b7 / DECRC \x1b8 资历更老,但在所有现代终端上效果完全一致。

  3. 3. 擦除 —— ED J 与 EL K

    两个结尾字节负责所有擦除:**J** 擦屏幕,**K** 擦行。每个都接一个范围参数:0(默认)从光标到末尾,1 从开头到光标,2 整屏 / 整行,J 还有 3 连滚动历史一起清(xterm 扩展,多数现代终端支持)。每个 TUI 启动时都会发的「清屏并归位」组合就是 \x1b[2J\x1b[H —— 擦掉整屏,再把光标移到第 1 行第 1 列。**ECH** \x1b[NX(见第 6 节)是就地变种:把 N 格覆盖成空白但不移动其他内容。要做局部重绘,先 CUP 跳过去再发 \x1b[K(擦到行尾)是清掉一行准备重画最省的写法。

  4. 4. 查询 —— DA、DA2、DSR、DECRQM

    终端会通过 **stdin** 回复的往返查询 —— 发出查询的程序必须读响应,否则它会泄到下一次用户输入里。**DA** \x1b[c(主设备属性)问「你是谁?」—— 现代终端回 \x1b[?<id>;<feature>;<feature>c,宣告 VT100 / VT200 / VT400 基础类 + 支持的特性(sixel、regis、彩色等)。**DA2** \x1b[>c 返回型号 + 固件版本 —— 用来分辨 iTerm2 / kitty / xterm。**DSR** \x1b[6n(光标位置)回 \x1b[r;cR\x1b[5n 返回终端 OK 状态。**DECRQM** \x1b[?<n>$p 读 DEC 私有模式 n 当前是 set / reset / permanent / unsupported(回复里的 0 / 1 / 2 / 3 / 4)。用途:在发 \x1b[?1049h 之前先检测 alt-screen 支持。

  5. 5. 边距与滚动区 —— DECSTBM r 与 DECSLRM s

    **DECSTBM** \x1b[<top>;<bottom>r 把滚动区域设为 topbottom 行(从 1 开始、含端点)。在这个区域内,向上 / 向下滚动(\x1b[NS / \x1b[NT)和 IL / DL 只影响这几行,其余屏幕保持不动。最经典的用法是底部的常驻状态栏 —— 设 \x1b[1;<screenrows-1>r,状态行永远不会滚走。要恢复全屏滚动,发不带参数的 \x1b[r。**DECSLRM** \x1b[<left>;<right>s 同样规则设水平边距,但要先开 DECLRMM(\x1b[?69h)才生效 —— 多数 TUI 完全不碰水平边距。没开 DECLRMM 时 \x1b[s 会被解读为 SCOSC(保存光标)—— 跨终端移植代码时最经典的模式混淆陷阱。

  6. 6. 插入 / 删除 / 光标形状 —— IL / DL / ICH / DCH / ECH + DECSCUSR

    不必整屏重绘的局部编辑。**IL** \x1b[NL 在光标处插入 N 空行,把现有内容下推(推出滚动区)。**DL** \x1b[NM 删除 N 行,把内容上拉。**ICH** \x1b[N@ 与 **DCH** \x1b[NP 在单行的列轴上做同样事。**ECH** \x1b[NX 在原位擦 N 格 —— 覆盖成空白但不移动其他内容,是清掉已知宽度字段最对路的原语。**DECSCUSR** \x1b[N q 选光标形状:1 闪烁方块(默认)、2 稳定方块、3 闪烁下划线、4 稳定下划线、5 闪烁竖线、6 稳定竖线 —— vim 的 terminal-mode26 之间切换以显示 insert vs normal 模式。被 xterm、kitty、iTerm2、wezterm、alacritty、ghostty、Windows Terminal、gnome-terminal 3.16+、konsole 支持;Linux console 忽略。

本家族的全部序列

浏览其他家族