跳到主要内容
ansicode

DECSET ?2026 — 同步更新模式

在帧结束信号到来前缓冲屏幕更新 —— 全屏重绘时消除闪烁。

字节形式

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

\\x1b[\x1b[?2026h (begin frame) \x1b[?2026l (end frame)
\\033[\033[?2026h / \033[?2026l
\\e[\e[?2026h / \e[?2026l
ESC [ESC [ ? 2 0 2 6 h / l
hex1b 5b 3f 32 30 32 36 68 / 6c

说明

最早由 iTerm2 + contour 提案,如今 kitty、wezterm、foot、ghostty、Windows Terminal、mintty、alacritty(1.7+)以及 tmux(直通)均已采纳。把整屏重绘包裹在 \x1b[?2026h(开始同步更新)与 \x1b[?2026l(结束)之间,终端会暂停渲染直到收到 l,然后一次性绘制最终状态 —— 消除 neovim、helix、tui-rs、ratatui 等程序在慢速 PTY(尤其 SSH)下的半帧抖动。不识别 ?2026 的终端按字节顺序绘制,因此可放心成对发送。需要严格检测的程序可用 DECRQM 查询 \x1b[?2026$p 并解析回报。建议单帧内 ≤ 100 ms —— 超时后终端会自动中止同步状态,避免屏幕卡死。

规范出处: Synchronized Output Mode (contour spec) / Mode 2026

示例

bash
printf '\033[?2026h'   # begin frame\n# … emit the full repaint here …\nprintf '\033[?2026l'   # end frame -> painted atomically
python
import sys\nsys.stdout.write('\x1b[?2026h'); redraw(); sys.stdout.write('\x1b[?2026l')
go
fmt.Print("\x1b[?2026h"); redraw(); fmt.Print("\x1b[?2026l")
javascript
process.stdout.write('\x1b[?2026h'); redraw(); process.stdout.write('\x1b[?2026l')
c
printf("\x1b[?2026h"); redraw(); printf("\x1b[?2026l");

在哪里用到

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

  • Helix editorHelix 把每次整屏重绘包在 `\x1b[?2026h` … `\x1b[?2026l` 里 —— 终端把一帧缓冲后原子翻页,宽窗格布局滚动大文件时不再有撕裂带
  • neovim (≥ 0.10) atomic redrawsnvim 用 DECRQM `\x1b[?2026$p` 探测;若返回 mode-2 / mode-3,每个 `redraw` 周期都包在 BSU / ESU 里 —— 调整大小、状态行更新、并排 `:diffupdate` 时收益明显
  • Ghostty, kitty, alacritty (0.13+), WezTerm四款都声明支持 DECSET 2026 —— 终端把每个字节排队,直到 ESU 抵达才一次性提交整帧;不声明支持,Helix / nvim 降级为逐格重绘
  • btop, btm, gtop dashboard TUIs高帧率资源监控(btop / btm)把内循环重绘包在 BSU / ESU 里 —— CPU / 内存柱不会更新到一半撕裂;不开同步时,滚动重绘慢的终端会看到旧柱与新柱之间的可见分界
  • tmux refresh, zellij pane resize复用器在 resize 和 `refresh-client` 时把窗格重绘突发包在 BSU / ESU 里 —— 每个窗格原子落地;不开同步时拆分窗口会短暂出现半绘制的窗格并排

常见问题

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

DECSET ?2026(同步输出)到底解决什么问题?
解决全屏重绘时的撕裂。当 TUI 每帧重写所有单元格,终端可能在更新中途绘屏 —— 用户在一两帧里看到上半屏新内容、下半屏旧内容。把重绘包在 \x1b[?2026h\x1b[?2026l 之间,告诉终端缓冲单元格更新、整帧原子翻转 —— 思路与双缓冲的 SDL/OpenGL swap 相同。Helix、Neovim、Ghostty 自带 TUI 以及现代 TUI 框架在终端宣告支持时都会启用。
启用 ?2026 前怎样检测终端是否支持?
用 DECRQM 查询:\x1b[?2026$p。支持的终端回复 \x1b[?2026;1$y(已置位)或 \x1b[?2026;2$y(已复位但识别)。不识别的模式回 \x1b[?2026;0$y 或干脆不回 —— 都表示不要用。非阻塞读、50ms 超时;无回复就假定不支持。Kitty、ghostty、WezTerm、Mintty、foot、iTerm2(≥3.5)都支持;xterm、gnome-terminal、konsole、Linux 控制台暂不支持。

终端支持

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

相关序列

在家族食谱中

DEC 食谱 · 6. 焦点事件与同步更新 —— `?1004`、`?2026`