最近在Linux终端里折腾opencode的时候,我发现一个特别恼人的现象:AI回复的对话内容明明整屏都是,我用鼠标拖来拖去就是选不中,按Ctrl+Shift+C复制出来要么是空的,要么只复制到零碎几行。更诡异的是,鼠标指针一旦移进opencode的界面区域,就从文本选择光标变成普通箭头,仿佛这个窗口里的文字被“锁”住了。
我一开始以为是opencode的问题,后来把几个常用的终端模拟器都试了一遍,又翻了一些TUI框架的文档,才算彻底搞明白:这不是bug,而是所有全屏终端交互程序在默认状态下都会启用一种“鼠标捕获”机制,把鼠标的操作权从终端模拟器手里接管走了。这篇东西就围绕这个问题展开,先讲清楚为什么复制不了,再给出我验证过有效的几种解决办法,覆盖不同终端、不同使用习惯,适合正在用opencode或者其他TUI应用的Linux用户顺手存档。
1. 不是你不会复制,是opencode这种全屏交互把鼠标接管了
1.1 全屏交互程序为什么要接管鼠标
先看现象背后的原理。终端里的程序分两类,一类像git log、ls,输出完就退出,它不关心鼠标;另一类是opencode这类全屏交互程序(TUI),它在启动时会通过终端转义序列切换到“替代屏幕”(alternate screen buffer),同时发送一串让终端开启鼠标跟踪的指令。终端模拟器收到这些指令后,就进入“鼠标事件上报”状态:你点一下、拖一下、滚动滚轮,终端模拟器不再当成本地操作,而是把鼠标按钮加坐标打包发送给这个程序,由它决定怎么处理。
这么设计的初衷很好理解:TUI程序需要响应点击、滚动、选择等功能,比如用鼠标滚动查看更长对话、点击某个按钮触发操作。opencode作为终端AI助手,对话内容通常很长,它需要把滚动行为接管过来,否则鼠标滚轮就会去滚终端自己的缓冲区,和程序内部滚动冲突。代价就是,它接管鼠标的同时,也把终端模拟器自带的“文字选择”功能给占用了。
所以你可以这样理解:终端模拟器平时像个普通文本编辑器,鼠标拖拽选择文字是它的“默认行为”;但opencode这类全屏程序运行起来后,相当于给终端打了电话,说“鼠标接下来由我来管,你不用管了”。终端模拟器很听话,就把选择功能让位了。这也是为什么你按Ctrl+Shift+C复制会得到空内容——因为终端里根本没有被选中的文本,它复制的是空气。
1.2 验证确实是鼠标捕获的问题
如果你拿不准自己遇到的是不是这个原因,可以做个特别简单的实验:在opencode界面里随便用鼠标拖一段文字,留意看有没有出现正常的文本选中高亮。如果完全没有高亮,同时你又能看到鼠标指针在某些按钮上方变成了可点击样式,那基本可以断定是鼠标捕获模式在起作用。
也可以再做一个对照组:先退出opencode,回到普通shell提示符,再用鼠标拖拽一下——你会发现一切正常,文字能选中,Ctrl+Shift+C也有效。这两下一对比,问题出在opencode的全屏交互层而不是终端本身,结论就很清楚了。
另外还有一个相关现象值得注意:当TUI应用处于替代屏幕时,有些终端模拟器的滚动缓冲区也会被“锁定”,你用滚轮滚上去看不到历史输出,因为历史内容被应用自己在内部管理了。opencode里按PageUp翻对话历史就是这个逻辑。这也解释了为什么你只复制当前屏幕的内容都费劲,更别提想翻回去复制几分钟前的内容了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 先记住一条通用出路:带修饰键选中文本
2.1 Shift为什么是默认
知道了原因,解决办法就很直接:你想让终端
