太长不看

  1. 在 macOS 上安装 Karabiner-Elements,导入 BryanHoo/Capslock-X 规则,实现将 CapsLock 修改为 超级键 Hyper Key,获得光标移动、选中、删除等一系列常用文本编辑功能。
    1. 做一个改动,将光标选择从 Hyper-Command-H/J/K/L 改为 Hyper-Shift-H/J/K/L。
    2. 跟据 Overriding macOS Diagnostics Shortcuts | xam.io 覆盖系统检测快捷键。
  2. 在 Windows 上安装 PowerToys,通过键盘管理器,将 CapsLock 变为右 Ctrl 作为“伪 Hyper 键”,再次实现上方的文本编辑功能。
    1. 多了 hyper 键之后,就可以承接所有的文本编辑需求,当作 macOS 上的 Control 来使用。
    2. 而原 Ctrl 则作为 Command 来使用,用于 UI 相关的操作,比如将复制粘贴重映射为 ctrl-insertshift-insert,可以解决 Windows 下容易不小心中断进程的问题。
  3. Alt 不设置全局快捷键,而是作为应用内的快捷键,因为快捷键的匹配逻辑是:先全局后应用,所以这个修饰键留给应用内的功能,避免冲突。
  4. 笔者不使用键盘右侧的修饰键,所以把他们作为单独的键盘层来使用。
  5. 在 macOS 上,将右 Alt 位(右 Command)设置为 option-command-control,到 Raycast 将快捷键绑定到应用上,实现快速打开常用应用,避免在启动台一大堆图标里面找应用。
    1. 这个功能在 Windows 上可以通过键盘管理器的快捷键打开应用功能来实现。
    2. 26 个字母已经足够覆盖常用应用了,所以剩余的符号键用来实现在中文输入法环境输入英文符号的问题。比如 右 Alt 位 - 逗号,发送英文逗号,减少输入法切换,双链笔记常常用到英文符号。
      1. 在 Windows 上用键盘管理器就可以实现。
      2. 在 macOS 上,要借助 Keyboard Maestro 或者 Hammerspoon 这类工具。
  6. macOS 将右 Ctrl 位( 右 Option)设置 shift-option-control,用于应用的全局能力。比如 Bob Translate 的全局翻译。
  7. 将右 Shift 位设置为切换输入法,避免操作失误而更改了输入法状态的情况。
  8. Leader key……

起因

公司提供 Windows 台式机,但是日常自己使用的是 Macbook,首先感受到的就是复制粘贴的修饰键位置不同带来的混乱,经常混淆复制粘贴的命令。据说有人能通过使用不同的键盘来区分不同的肌肉记忆,但我自己使用的却都是 75% 配列的键盘,无法从手感上区分两台电脑。

于是我想设计一套方案,能够减少我在两个系统之间切换的认知负荷。在看了大量的实践之后,我找到一套成本很低(免费软件,操作简单)的方案,其中最关键的是:对于编程最常用的文本编辑指令能够做到操作一致,也就是方向键上下左右、 单词的前进和后退、删除等。

后面又想到,既然做了文本编辑的快捷键,可以顺道设计其他功能的快捷键,比如全局打开应用、应用内的快捷键、全局功能的快捷键、全局输入英文符号。

希望最终达到的效果是:

  1. 健康:常用快捷键应该对手部操作来说更健康舒适的,不应该为了按键速度等因素加重手指和手掌的压力。
  2. 高效:这些快捷键在满足条件 1 的前提下,能够加快日常操作速度。
  3. 方便:这些快捷键应该是容易记忆的,不容易冲突的,不需要频繁地解决冲突问题。

实现这些效果,主要依靠两个免费的软件:macOS 上的 Karabiner-Elements,以及 Windows 上的 Microsoft PowerToys。辅助需要的 RaycastHammerspoon 也无需额外支出。

基础键位的改变

Capslock to Hyper

CapsLock 在键盘上有非常好的位置,但是使用频率却非常的少。将 Capslock 跟 Ctrl 交换已经是一个非常流行的做法。

写代码的时候,需要经常移动光标,简单地将光标在屏幕上前后上下移动一格,不过十几个 px 单位,而右手需要移动 约 10 厘米。所以我最开始的需求,变成了在统一 Windows 和 macOS 操作的同时,还能加速日常操作,做法就是 Hpyer 键与文本编辑相关的操作联系起来。

这里我采用的是 vim 风格的 HJKL,而不是 macOS 上自带的 NPBF 风格。

Q:为什么在 macOS 上不使用自带的 Emacs 风格文本编辑:Ctrl-npbf

A:因为我希望基于位置来记忆功能,而不是基于英文单词来记忆功能。基于英文单词来记忆有几个不便之处。首先,有些操作的英文短语并不好记忆;其次,英文单词容易重复,导致某些功能并不是基于单词含义而定义的。

基于位置的优势是,只要知道位置,就差不多知道了功能,即使用其他键盘布局,也能保持相同的操作位置。

位置,是键盘自定义最重要的属性,位置决定了手的动作、按键的手型。

通过这个抽象层,可以抹平 macOS 和 Windows 在文本编辑上的区别。比如说:

想要移动到行尾,使用 Hyper-O,在 macOS 发送 Command- 右箭头,在 Windows 发送 End。

位置很重要,相同的位置,就是相同的肌肉记忆,通过这种方式来减少在不同系统互相切换的摩擦。通过这个设置,在所有系统上,只要键盘的有 CapsLock 和 26 个字母,都能在一样的位置,实现一样的文本编辑功能,甚至无需在意具体究竟触发了系统的什么快捷键。

左侧修饰键

macOS 的 Command 在空格左边,虽然开始的时候,并不适应,但用一段时间之后,个人感觉用拇指来复制粘贴确实更为舒服,相比小拇指,手需要移动的距离更少,按起来更方便。

但 macOS 的键盘有一个问题,就是当你去搜索机械键盘,无法找到跟 macOS 一样的键盘,因为 macOS 自己有自己的一套设计,而机械键盘基本都是 ANSI 标准,除非买 Apple 自己出的薄膜键盘,某个没办法得到一样的键盘布局。

我更喜欢机械键盘的手感,所以我决定同时改变两个系统的键盘设置,将 Windows 的左侧三个修饰键改为 Alt Win Ctrl,而 macOS 时改为 option control command

Win 和 control 分别是 Windows 和 macOS 独有的按键,其余两个修饰键的功能倒是基本一致。

右侧修饰键

因为我习惯使用左侧修饰键,而几乎完全不使用右侧修饰键,所以右侧相当于多出来 3 个位置很好但是没有使用的按键。

设置右 Shift 为切换中英文状态,这样可以避免使用左 Shift 输入大写字母时导致的误操作。

设置右 Alt 位 + 字母打开常用应用,这里位置很顺手,26 个字母应该足够覆盖大部分人的使用场景。

而剩下来的刚好是符号键,我将这部分键位用于在中文状态下输入英文符号,如果你是 Obsidian 等双链笔记或者只是 Markdown 的用户,一定会有在文本输入 Markdown 格式符号的需求。在原来的状态下,需要“切换到英文状态 → 输入符号 → 切换到中文状态“,三步操作。在设置后,只需要 右Alt-1,就能立即得到一个英文的叹号,节省了各种切换。

对于 “<" 和“,“这种同一个按键上两个符号都有改变的情况,则再加上一个 shift。

设置右 Ctrl 位为各种应用的全局能力,这部分就看自己的需求了,比如我就设置了一个快速调起 Bob 翻译框的快捷键。

功能

统一全局快捷键

接下来的工作,就是在日常工作中发现两边使用上不一致的地方,依据某个记忆点,可以是 Windows 键位,也可以是 macOS 键位,慢慢统一到同一套操作。

比如 macOS 和 Windows 的全局截图我都统一设置为 Hyper-~

Windows 切换窗口改为 Ctrl-Tab。Windows 增加 Ctrl-Q 关闭应用。

全局打开应用

这个能力在 PowerToys 的键盘管理器可以直接某个快捷键打开应用,macOS 上通过 Karabiner-Elements 设置有些麻烦,我是直接用 Raycast 绑定应用。

全局输入符号

这个能力在 PowerToys 的键盘管理器可以用快捷键发送文本来实现。macOS 上 Karabiner-Elements 似乎没有提供这个能力,需要借助 Hammerspoon 来实现。我还在研究怎么在 macOS 上实现这个功能。

Hammerspoon 与 Leader Key

为了实现在中文输入法输入英文符号,我将右 Alt 位(标准美式键盘,也就是 macOS 键盘的右 Command 的位置)设置为 control-option-command

 hs.hotkey.bind({"ctrl", "alt", "cmd"}, ",", function()
    hs.eventtap.keyStrokes(",")
end)

hs.hotkey.bind({}, "F18", function() -- 为了避免触发系统检测,将左边的shift-control-option-command-comma 设置为 F18。
    hs.eventtap.keyStrokes("<")
end)
 

在实现这个功能的过程中,我无意中在 YouTube 看到了一篇关于 Hammerspoon 与 LeaderKey 的视频。所谓的 LeaderKey,我之前是从 vim 中了解到的,我非常喜欢这种概念,它将一次按下多个键的行为,转变为一些按键的序列,就如同是一个格斗游戏的连招。由此带来很多好处,首先不再需要一直按住修饰键,点击的手指压力比按住小很多,其次,这个按键序列单单只算字母键,n 次按键能够提供的快捷键数量是 $26^n$,差不多可以满足任何人的任何快捷键需求,而几乎不会产生冲突。

这个功能需要引入一个”Spoon“,使用方法在此:Hammerflow,具体功能介绍可以看下面的作者的视频。

A global leader key for Mac OS - YouTube

作者推荐使用右 Command(也就是美式键盘的右 Alt 位),我个人的做法是将 Leader Key 设置位 F20,触发方式同样是右 Alt 位,只需要在 Karabiner-Elements 中设置右 Alt 单独按下时为 F20,就能够实现。

通过这种方法,可以实现打开应用、打开链接、执行 Hammerspoon 命令…… 可折腾性非常高。

如果你不需要在中文输入法输出英文符号的功能,又不想使用 Hammerspoon,那么还有一个选择,在上面视频的评论区中有人推荐了 LeaderKey.app,这是一个开源软件,可以直观地配置 LeaderKey,还自带良好美观的 UI。具体使用可以看作者本人的视频:

The *faster than your launcher* launcher – Leader Key for macOS - YouTube

最后

大部分键位都能统一,但两个系统始终有一些细微的差别,做不到完全统一,比如 Windows 的 Win 键,但是我修改高频按键之后,似乎已经不太感觉到切换两个系统时的频繁冲突了,对这些快捷键的处理就没有那么紧迫。

最后,目前还没有解决的问题是

  1. 在 Windows 上,PowerToys 的键盘管理器不支持按键单独按下和作为组合键按下作为不同按键的功能。这有点麻烦,不能实现 Hyper 单独按下是 ESC 。
  2. 在 macOS 的终端和文本编辑的快捷键竟然不一致。比如在终端删除单词是 Ctrl-W,而 文本编辑删除单词是 Option-Backspace,后者在终端中无效。这方面感觉做得还不如 Windows,Windows 的 Ctrl-Insert 全局通用。这导致了文本编辑的删除部分快捷键无法在终端使用,现在也无法解决。
  3. Windows 上交换 Ctrl 和 Alt,会导致 Win-V 功能出现问题。这个 bug 好多年了,不知道什么时候能够修复。
  4. Windows 上的键盘管理器并不稳定,经常出问题,需要重启,但是两害相权,还是选择了改键。

可能的改进

  • 对于 Windows 上的问题,我感觉后面可能要换一个可编程键盘,在键盘层面修改键位更为稳定。
  • 如果你有解决以上的问题的方法,或者你对这套方案有什么疑问,欢迎分享你的做法或者留下你的问题。