跳到主要内容
ansicode

DECOM ?6 — 起点模式(把光标定位限制在滚动区域内)

让光标的行列原点 (1,1) 变为 DECSTBM 滚动区域的左上角,而非整屏左上角。

字节形式

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

\\x1b[\x1b[?6h (origin = region) \x1b[?6l (origin = screen)
\\033[\033[?6h / \033[?6l
\\e[\e[?6h / \e[?6l
ESC [ESC [ ? 6 h / l
hex1b 5b 3f 36 68 / 6c

说明

Origin Mode。通过 DECSTBM(\x1b[T;Br)划出滚动区域后,DECOM 决定后续光标定位指令(\x1b[r;c H CUP、\x1b[6n DSR-CPR 等)是把区域左上角视作 (1,1)(?6h 置位)还是把整屏左上角视作 (1,1)(?6l 复位,默认)。?6h 启用后:\x1b[1;1H 移到区域左上角,光标不能离开区域,DSR-CPR 报告相对坐标。常见于希望第 1 行作为屏幕固定状态栏、而主体(第 2 行至第 N-1 行的子矩形)独立运作的全屏表单式 TUI。注意:DECOM 是 DECSC(\x1b7)/ DECRC(\x1b8)保存与恢复的两个状态位之一。

规范出处: xterm-ctlseqs (DECOM, Private mode 6)

示例

bash
printf '\033[2;23r\033[?6h\033[1;1H'   # region = rows 2..23; origin mode on; CUP to its top-left
python
import sys; sys.stdout.write('\x1b[?6h')
go
fmt.Print("\x1b[?6h")
javascript
process.stdout.write('\x1b[?6h')
c
printf("\x1b[?6h");

在哪里用到

实际会发出该序列的工具——把抽象字节锚定到你已经用过的命令上。

  • vim / neovim window splits + `:set scrollbind`Vim 分屏为每窗口设 DECSTBM 滚动区域;启用 `scrollbind` 时,同步逻辑在跨窗口光标移动期间用 `\x1b[?6h` 让坐标局部化于窗口 —— `:set noscrollbind` 关闭后 DECOM 发送消失(`:set verbosefile=/tmp/v.log verbose=15`)
  • neovim floating-window scroll regions用 `nvim_open_win()` 创建的浮动窗口每个获得私有 DECSTBM 区域;当浮窗内容滚动时,neovim 发 `\x1b[<top>;<bot>r\x1b[?6h<draw>\x1b[?6l\x1b[r` 把坐标限定 —— 在浮窗上设 `relativenumber` 并用 `--log-level=trace` 跟踪可见
  • tmux pane scroll-region setuptmux 使用按 pane 的 DECSTBM 区域;对状态行 pane(`set -g status-position bottom`),主体区域为 `\x1b[1;<rows-1>r`,DECOM `\x1b[?6h` 让内部应用把左上角当作 `\x1b[1;1H` —— tmux ≥ 3.2 通过 `allow-passthrough on` 把 DECOM 协商到 pane
  • ncurses `setscrreg()` + `wsetscrreg()`设置按窗口滚动区域的 Curses 调用映射到 terminfo `csr`(`\x1b[<top>;<bot>r`);某些实现在应用请求按窗口相对坐标时还通过 `om` 布尔能力翻转 DECOM —— `infocmp -1 xterm | grep -E 'csr|om'`
  • less status line preservation via `?6h`+CUP composite`less ≥ 600` 配 `-N`(行号)在顶部保留固定状态行;`j`/`k` 的重绘循环发 `\x1b[<top>;<bot>r\x1b[?6h\x1b[<rel>;1H<content>\x1b[?6l`,让按帧 CUP 坐标保持相对于主体区域 —— `script -c 'less -N file' /tmp/log && strings /tmp/log | grep -E '\?6h|\[r'` 可观察

常见问题

针对这条序列,开发者真正会去搜索的问题的简短回答。

什么时候该用 DECOM \x1b[?6h(origin mode)?
仅在设置 DECSTBM 滚动区域*且*希望所有后续光标定位序列都相对于区域左上角而不是屏幕左上角的应用中使用。经典场景是固定状态行:用 \x1b[2;24r 设区域为 2–24 行,启用 \x1b[?6h,之后 \x1b[1;1H 落在第 2 行(区域顶),代码无须知道状态行偏移。多数现代 TUI 作者完全避开 ?6h,只在应用层偏置坐标 —— 跨信号处理器与崩溃路径少一个有状态模式要追踪。如果用了,把 set/reset 与区域生命周期配对,回到默认时一起发 \x1b[?6l\x1b[r,因为 DECSTBM 重置*不*清除 DECOM。
设置滚动区域后,为什么 \x1b[1;1H 落在第 R+1 行而不是第 1 行?
DECOM ?6h 处于激活状态。Origin mode 把所有后续 CUP / HVP / CHA / VPA 坐标重定基为相对于当前 DECSTBM 滚动区域顶部 —— 所以 \x1b[<top>;<bot>r\x1b[?6h 之后的 \x1b[1;1H 落在第 <top> 行第 1 列,*不是*第 1 行第 1 列。两种修复:(a) 需要绝对坐标时先显式 \x1b[?6l 关闭 origin mode 再移动,或 (b) 把绝对目标算为 <top> + relative_row - 1。注意 \x1b[r(重置区域为全屏)在任何现代终端上都*不*清除 ?6h —— DECOM 跨 DECSTBM 重置持续,症状被隐藏直到你设新区域。

终端支持

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

相关序列