DECSCUSR — 光标形状
切换光标形状:方块、下划线或竖线(可选是否闪烁)。
字节形式
涵盖所有常见的字符串字面量写法,方便正反查找。
\x1b[N\x20q (N = 0..6)\033[1 q\e[1 qESC [ N SP q1b 5b <N> 20 71说明
DEC 设置光标样式(DECSCUSR)。标准 CSI 序列,但末字节 q(0x71)前有一个 SPACE(0x20)中间字节:\x1b[<N>\x20q。参数在单一数值里同时编码 *形状* 与 *闪烁* —— 0 = 恢复用户默认、1 = 闪烁方块(出厂默认)、2 = 实心方块、3 = 闪烁下划线、4 = 实心下划线、5 = 闪烁竖线、6 = 实心竖线。首发于 xterm patch 282(2013 年 9 月);此后被每个现代 GUI 模拟器采纳。经典「编辑器模式」用法:vim 通过 t_SI / t_EI 终端串选项,把 \x1b[6\x20q(竖线)配为插入模式、\x1b[2\x20q(方块)配为普通模式;不少 shell(fish、zsh-vi-mode)在 vi 命令行编辑里做同样的事。
可移植性 —— xterm、iTerm2、kitty、alacritty、wezterm、gnome-terminal、Konsole、Ghostty、Windows Terminal、ConPTY 1809+ 全部完整支持 DECSCUSR。Linux console 部分支持(framebuffer 驱动接受形状变化但多数发行版忽略闪烁位)。Windows 旧 cmd.exe 部分支持 —— ConPTY 之前忽略;ConPTY 转发。Apple Terminal.app 晚期才加入,但能工作。最大的作者陷阱是 SPACE 中间字节:\x1b[6q(无空格)*不是* DECSCUSR —— 没有 SP 中间字节,末字节 q 会被解析成另一序列(多数模拟器上是 DECSTBM 相关)而光标毫无变化。字节序列必须严格为 ESC [ <N> SPACE q。terminfo 为 DECSCUSR 定义了 Ss cap(set cursor style),但多数 terminfo 条目并未填充,因此应用通常直接硬编字节。tmux 在现代版本中能正确把 DECSCUSR 转发给外层终端。
退出时恢复是可持久的清理。崩溃且未恢复用户偏好形状的编辑器,会让终端停留在 DECSCUSR 最后设定的竖线 / 下划线上 —— 用户回到 shell 提示符时被打个措手不及。标准清理是退出时发 \x1b[0\x20q(参数 0 = 「恢复用户默认」),通常接入到编辑器的 t_EI 或 atexit 钩子。更重的锤子是 DECSTR(\x1b[!p,见 decstr-soft-reset),它会在不清回滚的前提下顺带重置 DECSCUSR 等私有模式。注意「用户默认」由终端定义 —— 多数模拟器把参数 0 映射为闪烁方块,但 kitty / wezterm / iTerm2 尊重用户配置的默认,所以同一句 \x1b[0\x20q 在不同终端可能产生不同形状 —— 这是预期行为,不是 bug。相关:cursor-visibility(DECTCEM ?25 —— 与形状正交:可见性与形状,崩溃后都需要清理)、cursor-position(CUP —— 位置,第三个光标维度)、dec-cursor-blink(DECSET ?12 —— 仅闪烁开关、不动形状,需要单独覆盖闪烁而不强制形状时的替代品)。
规范出处: xterm-ctlseqs (DECSCUSR, CSI Ps SP q)
参数
| 0 | 用户默认光标 |
| 1 | 闪烁方块 |
| 2 | 实心方块 |
| 3 | 闪烁下划线 |
| 4 | 实心下划线 |
| 5 | 闪烁竖线 |
| 6 | 实心竖线 |
示例
printf '\033[6 q' # vertical bar (insert mode)\nprintf '\033[2 q' # block (normal mode)\nprintf '\033[0 q' # restore defaultimport sys; sys.stdout.write('\x1b[6 q')fmt.Print("\x1b[6 q")process.stdout.write('\x1b[6 q')printf("\x1b[6 q");在哪里用到
实际会发出该序列的工具——把抽象字节锚定到你已经用过的命令上。
- vim, neovim`guicursor` 按模式写 DECSCUSR——normal 用块,insert 用竖线,replace 用下划线
- fish默认 `fish_vi_cursor` 在 vi 模式切换时改变光标形状
- zsh + zsh-vi-mode pluginNORMAL 块、INSERT 竖线——在 line-init 钩子中发出
- bash with `bind 'set show-mode-in-prompt on'`支持 vi 模式的提示符在 command/insert 切换时发出 DECSCUSR
- starship — `vicmd_symbol` companion that also sets cursor shape
常见问题
针对这条序列,开发者真正会去搜索的问题的简短回答。
- 为什么
\x1b[6q不改光标形状,而\x1b[6 q可以? - DECSCUSR 在末字节
q之前需要一个空格(0x20)作为*中间字节*:线上形态严格是 ESC[<N>空格q。没有空格时,\x1b[6q会被解析成另一条(与 DECSTBM 相关的)CSI,光标完全不变。在\e引号字符串里别忘了空格——printf '\e[6 q'正确,printf '\e[6q'静默错误。 - 为什么 vim 退出后光标仍是方块,而不是恢复成竖线?
- vim 通过
t_SI/t_EI为*自己的*插入 / 正常模式配置光标形状,但除非t_te发出\x1b[0\x20q(DECSCUSR 0 = 恢复终端默认),它退出时并不还原用户先前的形状。.vimrc加let &t_EI = "\e[2 q" | let &t_te ..= "\e[0 q",或在提示符里发\x1b[0\x20q让每个新行重画。neovim 自 0.4 起开箱即用就正确处理。
终端支持
- 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 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 支持 | 部分 | 支持 | 支持 | 支持 | 部分 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
相关序列
在家族食谱中
CSI 食谱 · 6. 插入 / 删除 / 光标形状 —— IL / DL / ICH / DCH / ECH + DECSCUSR