只有 VS Code 里,输入法切到英文打出来的标点还是中文,排查记录
2304 字约 8 分钟
摘要在 VS Code 里用 Caps Lock 把微信输入法切到英文,字母是英文,逗号句号却是中文标点,别的应用都正常。我们先后怀疑了快捷键、EditContext、Karabiner、输入法版本,全被推翻,最后没找到根因,改成 Caps Lock 在微信输入法和系统 ABC 之间切换才彻底绕开。
有一天我在 VS Code 里写东西,发现一个很怪的现象:我用 Caps Lock 把微信输入法切到英文,字母是英文没错,可是敲逗号、句号,出来的却是 , 和 。。这个现象只出现在 VS Code 里,编辑器和里面的终端都一样,别的应用全部正常。
我记得以前遇到过,隐约觉得是个什么快捷键,就去问助手。
第一个猜测:误按了标点切换
助手一上来的判断是我误按了“中英文标点切换”的快捷键。输入法的标点状态和中英文状态是分开的,所以字母英文、标点中文并不矛盾。它让我先按一次 Ctrl + .,如果没用,就去输入法的偏好设置里看这个快捷键实际绑在哪。
我发了一张设置截图,里面这项叫“中文下中英标点切换”,快捷键是 ⌥⇧。。但我立刻意识到不对:别的应用都正常,所以不太像输入法的问题。
一路排除
接下来的几轮里,助手把能想到的方向挨个试了一遍。
- 查了 VS Code:没装输入法相关的扩展,也没有自定义快捷键。
- 怀疑新版 VS Code 在 macOS 上用 EditContext 接收输入,和中文输入法配合不好,让我关掉
editor.editContext,重启,没用。 - 在微信输入法的“默认英文的应用”列表里加上 VS Code,没用。
- 重启输入法,没用。
- Orca 和 VS Code 都是 Electron,内核版本几乎一样,Orca 里正常,所以不是 Electron 这类应用的通病。
有一个测试把问题缩小了。我在输入法里勾上“使用 shift 切换中英文”,关掉 Caps Lock,用 Shift 切到英文,标点就是英文的了。所以问题只出在 Caps Lock 这条切换路径上。
助手据此做了一个推测:在 VS Code 里,输入法没有收到 Caps Lock 的切换。灯亮了,我以为已经是英文,输入法却还认为自己在中文模式。开着 Caps Lock 时,拼音输入法会让字母直接上屏,所以字母是英文;标点照常按中文模式处理,所以是中文标点。这能对上所有现象,但没法直接验证。
嫌疑人轮流上场
我平时改过 Caps Lock 的行为,它先怀疑了 Karabiner。我的 Karabiner 里只有一条规则,用来去掉 macOS 对 Caps Lock 的防误触(需要按住一会儿才生效),它把每次按键都变成一次由 Karabiner 虚拟键盘发出的“按住 100ms 的 Caps Lock”。VS Code 会不会恰好接不住这种合成按键?我把规则关了,问题照旧。
接着它去看微信输入法本身。输入法 3.0.0 是 10 月 16 日更新的,程序里写死了一份开发工具名单,包括 VS Code、终端、iTerm2、Xcode、JetBrains 全家,Orca 不在里面,还有一段 Caps Lock 处理的逻辑,意思是关闭了 Shift 切换时,Caps Lock 开着只把字母改成小写直接上屏。这个解释太完美了,名单里有 VS Code,Orca 没有,所以只有 VS Code 出问题。
助手让我用名单里同样有的系统终端验证一下,我试了,终端里是正常的。我又补了一句,我说的是一个小时前还是好的,不是更新那天。这条线也断了。
助手最后回头去检查这个小时前后的变化:VS Code 配置只多了 Claude Code 扩展的几项设置,微信输入法拉过一次云端配置,两边都完全重启过,问题还在,这说明不是某个进程里卡住的状态。
我至今不知道这个问题为什么在那个时间点出现。
一个看似解决了的办法
这个问题我 10 月 8 日也遇到过,当时是让 Codex 处理的,症状一模一样,下划线变成 —,尖括号变成 《》,我记得当时好像不用重启就解决了。助手把那次会话翻出来,发现当时也排查过 EditContext、禁用全部扩展和 Karabiner,同样无效,最后的做法是:先用 Caps Lock 切到英文,然后按一次 ⌥⇧。,标点就恢复成英文,之后来回切换一直正常。
这次它之前让我在中文模式下按,按错了模式。我照新做法试了,结果是:英文模式的标点对了,可中文模式下的标点也跟着变成了英文。
原来在 VS Code 里,Caps Lock 切出来的英文模式没有自己的标点状态,和中文模式共用同一个。⌥⇧。 一按,两边一起变,要么都是中文标点,要么都是英文标点。上次 Codex 的办法只验证了英文模式,没检查中文模式。
让 Karabiner 代按标点切换,也失败了
既然手动按一次能切,就让 Karabiner 在 VS Code 里每次按 Caps Lock 的时候,顺便替我按一次 ⌥⇧.,这样切英文时标点跟着变英文,切回中文又变回来。
第一版规则没有任何效果。助手设计了一个测试:把 VS Code 里的 Caps Lock 临时改成只发 ⌥⇧.,不切换中英文,看三种情况属于哪一种。结果是中英文照常切换,说明这条规则在 VS Code 里根本没生效。是第一版判断“当前应用是 VS Code”的条件写得太严。放宽条件,让程序路径里含有 Visual Studio Code 也算匹配之后,才终于生效,标点能随 Caps Lock 一起切。
接着又冒出新问题。切换的时候偶尔会多打出一个 ˘。这是美式键盘上 ⌥⇧. 本来对应的字符,说明这一下按键没被输入法当成标点切换,而是被当成普通按键送进了 VS Code。助手推测是 Caps Lock 刚亮起时,输入法会让按键直接上屏,就调整了发送顺序,保证 ⌥⇧. 总是在中文模式下发出。我试了,英文切回中文的时候还是会出现 ˘,之后就切不回来了。
最后压垮这条路的是我自己发现的一个现象:我用 Cmd+Tab 切到 Orca 和助手聊天,打出来的标点全是英文的。
微信输入法的“中英标点”开关是全局的,不是只管 VS Code。我的规则在 VS Code 里把它切成了英文标点,离开 VS Code 之后,所有应用的中文模式都跟着变成英文标点。Karabiner 感知不到我切换了应用,所以没办法在离开的时候再切回来。这条路彻底走不通。助手立刻把 Karabiner 配置从备份还原成当天改动之前的样子。
最后的办法:绕开输入法的英文模式
既然输入法里“Caps Lock 切英文”这一条在 VS Code 里不可靠,那就不用它。我让助手改成这样:在所有应用里,Caps Lock 都在微信输入法(中文)和系统自带的 ABC 输入法之间切换。
- 英文直接用 ABC,不再用微信输入法的英文模式,也不再动标点开关,所以切应用时标点不会乱。
- Caps Lock 灯不会再亮,靠菜单栏的输入法图标区分中英文。
- 需要真正锁定大写的时候,按
⇧ + Caps Lock。 - 原来那条去掉 Caps Lock 防误触的规则并进了新规则:既然按一下 Caps Lock 本来就是切输入法,系统的防误触延迟不再有影响。
我测了:VS Code 里切到 ABC,打 ,.;_ 都是英文标点;切回微信输入法,打 ,。 是中文标点;Cmd+Tab 到别的应用,标点也都正常。我说:“效果非常 nice。”
回头看
这次的排查走了很多弯路,值得记下来的有几点。
第一,我的两句话各推翻了助手的一个很漂亮的推测。“终端里是正常的”推翻了开发工具名单的解释,“一小时前还是好的”推翻了输入法更新的解释。助手的推测每次都自洽,但自洽不等于对,一个能验证的小测试比一个完美的故事更有用。
第二,一个看似解决的办法要在两个状态下都检查。上次 Codex 的办法只验证了英文模式,这次就吃了亏。
第三,根因我没有找到。这个问题在一小时之内从正常变成异常,两边的进程都重启过也没有恢复,我只知道 Caps Lock 的切换在 VS Code 里没有被输入法正确接住。我最后换成的是一个绕开它的办法,不是修好它。
适用边界这是我这台机器上、这个版本组合下的做法:微信输入法 3.0.0,VS Code 1.142,Karabiner-Elements。键盘事件的路径可能因输入法、系统版本和键盘不同而不同。如果你遇到同样的现象,可以先用 Shift 切换做一个对照测试,看问题是不是只出在 Caps Lock 这条路径上。