【声明】本博客所有内容均为个人业余时间创作所述技术案例均来自公开开源项目如GithubApache基金会不涉及任何企业机密或未公开技术如有侵权请联系删除标题147、【Agent】【OpenCode】启动分析ANSI DEC背景上篇 blog【Agent】【OpenCode】启动分析SGR 参数分析了 ANSI 序列中\x1b[38;5;214m这里的三个数字位置是严格固定的由 ISO/IEC 6429即 ANSI X3.64 / ECMA-48国际标准定义是终端模拟器解析 SGR 序列时必须遵守的语法规范其中 SO/IEC 6429 和 ECMA-48 本质上是同一份标准的不同发布版本其中 ISO 官方标准是付费文档而 ECMA-48 是免费公开的接着分析了\x1b[38;5;214m是一个复合参数序列三个数字各自占据不可交换的语义槽位如果位置错乱的话跳过或调换任何一步解析就会失败或产生完全不同的效果第一个参数决定做什么而第二个参数仅当第一个是 38/48/58 时存在决定用什么颜色空间这种多层设计是历史演进的结果下面继续分析OpenCodeOK接着看这里的\x1b[?25l和\x1b[?25h这两个序列属于 ANSI 转义序列中的 DEC 私有模式DEC Private Mode专门用于控制终端光标的显示与隐藏它们不是 SGR 指令不以m结尾而是以?开头以h/l结尾的模式切换指令首先是\x1b[?25l隐藏光标片段含义说明\x1b[CSI 引导符控制序列起始标志?DEC 私有模式标识表示接下来的参数是 DEC 私有扩展而非标准 ECMA-48 参数25模式编号DEC 内部定义的光标可见性模式lReset / Disable关闭该模式小写L代表 low接着是\x1b[?25h显式光标片段含义说明\x1b[CSI 引导符同上?DEC 私有模式标识同上25模式编号同上hSet / Enable开启该模式代表 high这里h和l的记忆技巧h High / Showl Low / Hide这对助记符适用于所有的 DEC 私有米寿这里进度条之所以要隐藏光标是因为进度条会通过\r不断原地刷新同一行如果光标保持可见会出现两个严重的视觉问题光标闪烁干扰每次\r覆盖写入时光标会在进度条末尾快速跳动闪烁产生刺眼的视觉噪声残影风险在某些终端中光标所在位置的字符可能被终端渲染引擎特殊处理比如反显导致进度条某个字符颜色异常隐藏光标后整个进度条区域变成纯粹的文本渲染刷新过程干净流畅迁移完成后立即恢复光标确保用户后续交互不受影响下面是进度条的完整生命周期\x1b[?25l ← 进入进度条前隐藏光标 ↓ \r${bar}${pct}%← 循环刷新进度条无光标干扰 ↓ \n ← 进度完成换行 ↓ \x1b[?25h ← finally 块中恢复光标无论成功还是失败都会执行这里\x1b[?25h被放在 finally 块中这是关键的防御性编程即使 JsonMigration.run 抛出异常光标也一定会恢复如果把恢复逻辑写在 try 块内异常则会导致光标永久消失用户的终端将处于不可用状态另外25 只是众多 DEC 私有模式之一下面是终端编程中常用的几个 DEC 模式模式号h开启l关闭用途25显示光标隐藏光标OpenCode 这里用的1049进入备用屏幕缓冲区返回主屏幕vim / less 等全屏程序使用2004启用粘贴括号模式禁用粘贴括号模式防止粘贴内容被误执行1000启用鼠标追踪禁用鼠标追踪TUI 应用接收鼠标事件7启用自动换行禁用自动换行控制行尾行为关于 SEC 私有模式目前没有一个统一现存的官方标准文档主要是因为 DECDigital Equipment Corporation公司已经在 1998 年被 Compaq 收购后并入 HP原始硬件手册早已停止维护且未整体数字化公开目前业界公认的的权威文档可参考 XTerm Control Sequences网址https://invisible-island.net/xterm/ctlseqs/ctlseqs.html说明由 xterm 维护者 Thomas Dickey 持续更新至今由于现代终端模拟器几乎都以 xterm 为兼容基准这份文档实际上取代了 DEC 原始手册的地位查阅方式比如可以搜索DEC Private Mode与 SGR 的核心区别特征SGRDEC控制对象文本样式颜色粗体暗淡终端行为光标屏幕鼠标终止符mh / l参数前缀无?状态特性属性叠加可组合开关式非开即关标准来源ECMA-48 / ISO 6429DEC VT100 硬件文档事实标准OK本篇先到这里如有疑问欢迎评论区留言讨论祝各位功力大涨技术更上一层楼更多内容见下篇 blog【Agent】【OpenCode】启动分析stderr