Tana 全局快捷键自定义失效:schema 键名与实际读取键名不一致

Issue 编号:102
创建:2026-09-04T07:14:08Z
更新:2026-10-27T04:48:38Z
状态:open
标签:["blog:publish", "笔记", "效率", "macos", "AI 写作为主"]

正文

背景

Tana 桌面端(Electron 应用)有一个全局语音捕获功能,默认快捷键 Cmd+Shift+E,通过 Electron 的 globalShortcut 注册——全局生效,Tana 在后台也会被触发。这个组合键容易和滴答清单的主窗口唤起(Cmd+Control+E)误触,所以想把它禁用掉。
思路是:把快捷键改成一个物理上不存在的键(如 F24),等效于禁用,又比塞非法字符串干净(注册能成功,不产生错误日志)。

踩过的坑

直接改配置文件 ~/Library/Application Support/Tana Outliner/keyBindings.json:
改完重启,Cmd+Shift+E 依然生效。看起来像是「设置了 custom 不会禁用 default,两者并存」——但这是错觉。

真正的原因:键名不一致

读 Tana 的 main.js(版本 1.523.0)取证,发现两处键名对不上:
位置
键名
store schema 声明(KRe)
toggleVoiceCapture(遗留名,全代码只出现一次,没有任何地方读它)
命令列表(dre)里的 command
voiceCapture
实际读取:store.get(e.command)
voiceCapture
快捷键管理器的注册逻辑本身是替换,不是并存:
但 getKeyBindings() 读的是 store.get("voiceCapture"),而我们写的是 toggleVoiceCapture → 读到 undefined → falsy → 静默回退到默认值 Cmd+Shift+E。自定义配置被无声地忽略了。
本质上是 Tana 自己的一个 bug:schema 里的遗留键名和实际读取的 command 名不一致。

正确的写法

Tana 的 GUI 入口(Options → Customize Keybindings)内部也是用 command 名写入的,所以这和 GUI 设置完全等效。

另外两个操作要点

  1. 改配置前必须先退出 Tana。Tana 用 electron-store 管理配置,App 退出时会把内存中的值写回文件;在它运行时改 JSON 会被静默覆盖。流程:备份 → 优雅退出 → 改配置 → 重启 → 读回验证。
  1. 不要试图用空字符串「禁用」。取值逻辑是 customShortcut || defaultShortcut,空串是 falsy,会静默回退默认值,你以为禁了其实没禁。要用合法但按不到的键(F24 在任何 Mac 键盘上都不存在,Electron accelerator 支持 F1–F24)。

替代方案:不一定要禁用全局捕获

Tana 还有个非全局的语音入口:Cmd+Shift+L(Quick chat with dictation),只在 Tana 前台生效。如果需要的只是「在 Tana 里语音输入」,禁用全局捕获后改用它就够了。代价是失去 Tana 语音捕获最值钱的能力——在别的 App 里(比如浏览器看资料时)不用切窗口直接说话记进 Tana。

一键禁用脚本

以下脚本可直接分享使用:自动退出 Tana → 备份 → 写入正确的键名(保留其他配置、清理无效的遗留键名)。已在 macOS 上验证。
如果只想粘贴一行(需先手动退出 Tana):

经验总结

逆向修改 Electron 应用的配置文件前,先确认代码实际 get() 的键名,而不是看 schema 声明。 schema 可能留有历史遗留键名,写错了不会报错,只会静默失效——排查时容易误判成「配置机制和预期不同」(这次就误判成了 custom/default 并存)。
原始 Markdown(保真归档)
上一篇
Quick PR Tool v1.0.17 - 新增 Back to Source Branch 功能
下一篇
我给自己写的几个 Obsidian 插件