什么是 Karabiner-Elements ?
Karabiner-Elements (下面我们简称为Karabiner)官网对自己的描述是 “A powerful and stable keyboard customizer for macOS.”,我使用下来的感受是 Karabiner-Elements 是 macOS 平台上一款非常强大的键位映射工具,没有吹嘘的成分,买家秀和卖家秀是一样的。
这个介绍我会分为两个部分:
- part1 介绍
Karabiner
的核心功能,以及我自己使用Karabiner
帮助我高效使用键盘的一个思路,不涉及具体的配置 - part2 根据实例详细介绍使用 Karabiner 高级映射的配置和高级用法,满足一些高级自定义的需求
下面我尽量使用通俗易懂的语言来表达,简单来划分 Karabiner
核心功能的话,Karabiner
可以分为 简单修改
(Simple modifications
) 和 复杂修改
(Complex modifications
),我更倾向于称之为 简单映射
和 高级映射
。
简单映射
简单映射
其实就是 一对一
的键位映射关系,比如很多因为 Caps lock 键的位置非常好,但是又不经常用,所以喜欢把 Caps lock 映射到 Control 上,当按下 Caps lock 键的时候,实际触发的是 Control 键,非常方便。(这也是 HHKB 默认把 Left Control 放到 Caps lock 位置的一个原因吧)
这么简单的修改,肯定很多朋友会说,那我在 macOS 系统的 Preferences 里也可以修改啊:
Karabiner 的简单映射能做的远不止这些,除了支持 Control/Cmd/Shift/Option
等这些修饰键,还有以下 macOS 系统不支持的功能:
- 支持所有的按键的映射,可以精确区分左右侧的功能键,比如
left control
/right control
可以映射到不同的键位上,支持所有字母、数字、f1-fn
、媒体键、方向键 - 甚至支持鼠标按键以及各类侧键(
button4
,button5
)的映射 - 支持根据不同的硬件设备(Target device)进行不同的映射,比如我的
HHKB
和KeyChron K6
,或者MBP
自带键盘都可以根据实际需要,使用不同的映射策略
高级映射
简单映射是一对一的映射,那么高级映射,泛指可以支持一对多的映射,外加条件映射的高级复杂映射。我们还是拿个简单的例子,很多朋友喜欢把 Caps lock
键映射为 Hyper
键,Hyper
一般是采用 Control Cmd Option Shift
四个键的组合。这样,当我按 Hyper C
的时候,相当于按下了 Control Cmd Option Shift C
,使用 Hyper
键的好处是,很难和其他的内置的 hotkey 冲突,因为基本上不会有 app 内置这么复杂的 hotkey。
PS: 我的 Hyper key 是实用 fn
键实现的,相比 Control Cmd Option Shift
有诸多的好处,后面会详细解释。
另外复杂映射,不像简单映射在 UI 简单选择一下即可使用,而是需要编辑一个 json
配置文件,它有自己的配置格式,按照文档约定的属性进行配置即可。
因为本文主要是想跟大家分享一些思路,这里不会太涉及到配置文件的设置。大家看完之后,可以参考我的配置文件或者网上分享的配置文件,也可以去官网查看详细的文档。
再比如,习惯了在 Vim
中使用 hjkl
的朋友,想在其他非 Vim
环境下也使用类似功能的话,也可以使用 Karabiner 间接的实现,需要下面几步:
- 把
Caps lock
键映射到hyper
键上 - 把
hyper h
映射到left_arrow
左方向键上 - 同理,把
hyper j/k/l
分别映射到 下/上/右 方向键上
这样,当我们按下 Caps lock h/j/k/l
时候,就相当于按下方向键了。
再举个例子,比如不同的编辑器或app下(比如 VSCode 和 Xcode)的 跳转到上一处修改
/下一处的修改
是不一样的,如果希望这些体验是一致的,我们可以针对不同的 app 进行单独配置。
App/前进后退键 | 前进 | 后退 |
---|---|---|
Xcode | Control Cmd -> | Control Cmd <- |
VSCode/Chrome | Cmd ] | Cmd [ |
当然还有一些其他的 IDE 或者 app 也有类似的功能,我们想把他们的体验统一起来,那么我们可以这么做:
- 针对 Xcode app,把
Hyper ]
映射为Control Cmd ->
,把Hyper ]
映射为Control Cmd <-
- 针对 VSCode/Chrome,我们把
Hyper ]
映射为Cmd ]
,把Hyper ]
映射为Cmd [
我使用 Karabiner 解决了我的哪些困扰?
Caps lock
键映射到Hyper
键,要注意的是- 为保持操作统一,HHKB 下需要把
Left Control
映射到Hyper
键,Karabiner 支持根据不同设备,映射到不同按键上 - 我们需要个
Hyper
键的原因是,我们在自定义一些键位的时候,使用 Hyper 键进行修饰,不容易和系统以及 app 内置的热键冲突,这个是基础。
- 为保持操作统一,HHKB 下需要把
- 常用的
VIM
导航键的设置,包括:hyper h/j/k/l
方向导航键,每次前后移动一个字符,上下移动一行hyper y/p
向后/前移动一个 word,这里和 Vim 的体验并不同,只是我个人的习惯hyper d/u
向下/上 移动15行(具体行数可以自定义)hyper o
在下面插入一个空行
- 替代
Control
的一些组合键,如果我是用的HHKB
的话,相当于把Control
键映射到了Hyper
键,那么之前经常使用的一些组合键,比如Control a/e
跳转到行首/行尾等就很难按出来了,所以我这里我给常用的一些Control
作为修饰键的组合键提供了一些映射:Hyper a/e
=>Control a/e
Hyper c/b/r
=>Control c/b/r
(中止命令执行,tmux,iterm2 搜索)
- 一些方便的操作
Hyper i
=>delete
,主要原因是我有几个不同的键盘,HHKB 和 Keychron K6 的 delete 键位置不太一样,导致我很容易按错。所以我就想着把他们统一到一个位置上,选择 i 键的原因是它在右手食指上方,很容易按。为了习惯它,我一度把delete
键本身给映射到一个空键上,强迫自己习惯使用hyper i
键做删除。Hyper w
删除当前光标所在位置的单词/词组,类似Vim
里的diw
(delete in word),不管光标位置在当前单词/词组的哪个位置,都可以直接删掉整个单词,很多时候还是挺好用的。
- 输入法切换,MBP 内置键盘上
Caps Lock
键可以切换输入法,映射到Hyper
之后就没有一个比较舒服的切换输入法的按键了。另外一个切换的时候,我还需要清楚当前是什么输入法,将要切换到什么输入法。有没有办法可以直接切换到某一个输入法呢?Karabiner 考虑到了这个问题(可能是 Karabiner 的作者是个日本人,也有在英文和本土语言输入法之间切换的烦恼),我是这么映射的:Hyper <
切换到英文输入法Hyper >
切换到中文输入法 这样的话,我就不需要记录当前是什么输入法,我只需要关心我接下来希望使用什么舒服法就行了。不过这两个按键,我现在还没形成肌肉记忆
- 使用连续按键,打开常用的 app,比如:
o,x
打开/唤起Xcode
o,g
打开/唤起Google Chrome
o,i
打开/唤起iTerm2
o,t
打开/唤起Tower
- 等等。。
所谓连续按键,比如
o,a
就是按完o之后马上按a,就可以触发打开Xcode
的命令
以上问题的思路,都会考虑到可能会使用到多个不同的键盘的case,并保证体验是一致的,不会出现换个键盘,还需要重新熟悉键位的尴尬情况。
为什么我选择使用 fn 键作为 Hyper 键,而不是 Control Command Option Shift?
在这之前,我们先聊一下什么是修饰键(modifier keys
),所谓修饰键就是可以和其他按键一起按,达到一个组合键的目的。macOS
上,精确地说,有以下这些修饰键:
left_command
,right_command
left_control
,right_control
left_option
,right_option
left_shift
,right_shift
caps_lock
fn
比如,我可以按 left_command c
进行复制,但是不能定义 6 c
来执行一个操作,因为 6 和 c 都是非修饰键,起不到同时按到达组和键的目的。
接着我们要明确我们需要 Hyper
键的目的,它主要是作为我们常用自定义按键的通用修饰键,而且这个键需要不经常使用,从而不会和内置的系统热键,或者一些app的内置热键冲突。所以 hyper
键只能是这里面的其中某一个,或者他们的组合。
Control Command Option Shift
是一个很好的 Hyper
的候选,我搜索了一下,非常多的朋友在使用。不过他有个问题是,它直接用尽了 Control Command Option Shift
四个修饰键,没有再使用这四个按键的某一个作为增补修饰键的可能。举个例子,我上面定义了 hyper h
映射到 左方向键,那么如果我想往左边选择的时候,会下意识地会再加一个 Shift 键,但是发现没有起作用,因为 Hyper
里已经使用了 Shift
,再次按下 Shift
并不会执行选择的操作。
遇到这个问题之后,我就继续找其他替代方案。开始尝试使用 fn
键作为 hyper
键,发现它还蛮好用,因为很多键盘上都没有 fn
这个键,所以它不会经常会被内置为默认热键里的修饰键,而且它还可以继续和 Shift/Option
等修饰键进行组合。
比如上面我定义的 hyper h
映射到 左方向键,那么就有:
hyper shift h
==shift left
向左选中hyper option h
==option left
向左跳过一个wordhyper cmd h
==cmd left
跳到行首
非常完美