HVP — 水平与垂直定位(CSI f,CUP 的别名)
将光标移动到绝对 (row, col) —— 语义与 CUP 完全相同,仅末字节用 f 而非 H。
字节形式
涵盖所有常见的字符串字面量写法,方便正反查找。
\\x1b[
\x1b[<row>;<col>f\\033[
\033[1;1f\\e[
\e[1;1fESC [
ESC [ row ; col fhex
1b 5b ... 66说明
Horizontal and Vertical Position。ECMA-48 §8.3.61 定义 HVP 的语义与 CUP(\x1b[r;cH,§8.3.21)完全相同 —— 移动光标到绝对的 1 起始行/列,默认 (1,1),超界值钳到可视区域。差别仅在末字节:CUP 是 H(0x48),HVP 是 f(0x66)。两种形式在野外都常见 —— 一些程序仍使用更老的 f 形式,尤其是 curses 默认能力表的部分项与某些 DEC VT 克隆的测试向量。解码时把 HVP 等同于 CUP;新代码请发送 CUP(H),除非需要匹配遗留流。注:ECMA-48 历史上把 HVP 视作主要原语而 CUP 是同义;xterm-ctlseqs 反过来把 CUP 作为主形式,反映现代用法。
规范出处: ECMA-48 §8.3.61 (HVP) / xterm-ctlseqs
示例
printf '\033[2;5fHello at (2,5)\n' # same as \033[2;5Hprint('\x1b[2;5fHello at (2,5)')fmt.Print("\x1b[2;5fHello at (2,5)\n")process.stdout.write('\x1b[2;5fHello at (2,5)\n')printf("\x1b[2;5fHello at (2,5)\n");在哪里用到
实际会发出该序列的工具——把抽象字节锚定到你已经用过的命令上。
- DEC VT510 RM applications (historical)DEC 的 VT510 参考手册把 HVP 作为规范的定位序列 —— 1990 年前对照 VT100 系列手册编写的 VAX / VMS 程序到处发 `\x1b[<r>;<c>f`,尽管完全可以用 CUP。现代工程师遇到 HVP 的主要场合就是阅读这些遗留清单
- WordPerfect for DOS cursor positioningWordPerfect 5.x 在 DEC 与 IBM-3151 终端上用 HVP 定位单元格 —— Windows 移植版去掉了 HVP 支持,但归档使用的 DOS 可执行文件在 DOSBox 经真串口外接时仍会产生该字节序列
- ncurses fallback when `cup` cap is missing若 terminfo 条目缺 `cup`(光标定址)能力但定义了 `hpa` + `vpa`,ncurses 回退到 HVP 风格的组合定址 —— 实际上罕见(现代条目都有 `cup`),但 `tic` / `infocmp` 在条目作者写明时会编译 `cup=\E[%i%p1%d;%p2%df` 能力
- mosh state-replay enginemosh 的终端状态差分回放在 SSP 帧重建阶段把 CUP 与 HVP 视为完全等价 —— 解析器把 `H` 与 `f` 末字节映射到同一 `move_cursor(row, col)` 状态变更,于是发 HVP 的遗留流在重连时也能正确回放
- `tic` / `infocmp` terminfo round-trip用 `infocmp -L` → `tic` 往返一个老的 `vt100` 或 `vt220` terminfo 条目,会保留作者使用的 HVP 形式 `cup=\E[%i%p1%d;%p2%df` —— 在把 1990 年代主机的 terminfo 条目移植到现代 Linux 且希望保持字节级一致的输出流时有用
常见问题
针对这条序列,开发者真正会去搜索的问题的简短回答。
\x1b[<r>;<c>f(HVP)与\x1b[<r>;<c>H(CUP)一样吗?- 在支持矩阵里所有终端上实际相同。ECMA-48 规定 HVP 与 CUP 定位语义一致 —— 同样从 1 起、同样在省略时默认
Pn1/Pn2为 1、同样不滚动地移动光标。历史区别在于 HVP 属于不同 ECMA 类别(呈现控制 vs 编辑控制),可被 SCS 单独抑制 —— 在现代终端上无关紧要。事实约定是用 CUP\x1b[H,因为它是大家最先实现的字节;只在已有代码使用时保留\x1b[f。 - 什么时候用 HVP
\x1b[f而不是 CUP\x1b[H? - 几乎从不 —— 新代码选 CUP
\x1b[H。实际用 HVP 的唯一理由是读老代码,或解析器源头已基于f编写。ECMA-48 保留两者以满足规范一致性,但支持矩阵里每台模拟器都对它们一视同仁。若你的输出栈剥离其中之一(罕见 —— 通常仅 DEC VT510 RM-strict 解析器),另一个仍能通过;否则纯属风格选择。
终端支持
- 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 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |