iTerm2 选中文本突然失效?一次 AI Coding 工具鼠标劫持回归的排查
症状:iTerm2 里打开某 AI Coding 工具,想复制一段输出——选中第一行,按住 Shift,点最后一行,以前能整段选中,现在不行了。
不是你的操作变了,是工具更新抢了你的鼠标。
排查过程
第一步排除 iTerm2 设置。Preferences → Pointer 里 “Emulate third button” 选项、General → Selection 里的 “Copy to pasteboard on selection” 都正常。切回普通 shell,shift+点击选区完全正常。
第二步排除鼠标驱动。同一个终端窗口,切到普通 zsh 面板选区正常,一进该工具的 REPL 就失效。问题边界明确了:仅在该工具运行状态内失效。
第三步搜 GitHub issues。找到了一个完全对上的 bug 报告:该工具在 v2.1.195 版本开始,在终端内部劫持了鼠标事件(点击、拖拽、悬停),用来实现”点击展开”、hover 高亮、滚动加速这些交互功能。副作用就是——你没法再用鼠标正常选文本了。
根因:鼠标事件被接管
该工具新版本的鼠标劫持做了什么:
旧版本:鼠标事件 → iTerm2 原生处理 → 正常选区/复制
新版本:鼠标事件 → 工具拦截 → 用于内部交互(点击展开/hover高亮/滚动加速)
↑
Shift 可绕过,但有 bug
你记得的”之前能 shift+首行、shift+点末行整体复制”——那是旧版本根本没有抢鼠标,iTerm2 原生选区正常工作。
新版本抢了鼠标之后,Shift 成了”强制交回给终端”的绕过键,但这个绕过路径有 bug,导致你按 Shift 点最后一行时,选区没有被正确扩展。
这跟广告系统上新策略一模一样:新逻辑上线 → 覆盖了旧行为 → 用户发现指标异常 → 排查到是抢占了不该抢的东西。
修复
当前版本没有 settings.json 字段也没有 CLI 参数可以关,只能用环境变量绕过:
export CLAUDE_CODE_DISABLE_MOUSE_CLICKS=1
写入 .zshrc 持久化:
echo 'export CLAUDE_CODE_DISABLE_MOUSE_CLICKS=1' >> ~/.zshrc
source ~/.zshrc
然后重新打开该工具会话,鼠标事件不再被劫持,iTerm2 原生选区恢复。
滚轮加速不受影响——这个环境变量只关点击/拖拽/悬停劫持,滚轮还是被该工具接管以保持加速体验。
元结构映射:广告系统里的回归事故
排查这个问题的过程和排查线上广告事故一模一样:
| 步骤 | 广告系统事故 | 本次排查 |
|---|---|---|
| 1. 确认异常 | CTR 暴跌 / 营收下降 | 选中文本失效 |
| 2. 缩小范围 | 哪个模块上线了? | 只在某工具内失效,zsh 正常 |
| 3. 定位变更 | diff 最近发布的代码 | 对 bug report,确认 v2.1.195 引入 |
| 4. 止损 | 回滚 / kill switch | CLAUDE_CODE_DISABLE_MOUSE_CLICKS=1 |
| 5. 修复 | 修 bug 上线 | 等上游修复,当前绕过去 |
本质是一样的:新功能上线 → 覆盖了不该覆盖的旧行为 → 用户发现异常 → 开关兜底。
教训
三条:
1. 工具频繁更新时,先怀疑工具。 尤其是 AI Coding 工具迭代极快,每周都有新版本。出了问题先别急着改自己的配置,搜一下是不是新版本的回归。
2. 终端应用不该劫持终端本身的行为。 鼠标选择是终端的基础能力,就像广告系统里你不能为了加个新 feature 把曝光日志停了。新功能应该在不破坏旧功能的前提下实现。
3. 任何时候都要有 kill switch。 该工具提供了一个环境变量关掉鼠标劫持——这就是 kill switch。好设计师会在新功能旁边放一个关闭它的方式,因为任何新功能都可能出 bug。
一句话:不是你操作变了,是工具更新默认接管了鼠标交互——加一个环境变量关掉这个接管就行。