不知道怎么说起,先列一下起因的关键词:mac 键盘,iterm2,emacs。这里面的每一个词都是我要解决的问题起源,也是有这篇文章的原因。这里的环境是 Ventura 13.6.6,iterm2 3.5.0,后面软件有更新的话可能配置路径不一样。
注意这里修改的是默认的配置文件,就不一一强调了。
首先是一个很多人都会遇到的问题:在 iterm2 中用 emacs(或者说在 iterm2 的命令行中用 emacs-style key binding)的时候 meta 键的映射。这个在网上已经有很多人写过了,就是在 iterm2 的 Settings -> Profiles -> Keys -> General
中,把其中的 Left Option key
的选项改为 Esc+
,这样在终端中 option
键的行为就和其它键盘的 meta
行为一样了。
但是因为 mac 键盘中左边 option
的位置比较靠左一点,导致用左手大拇指按起来很别扭,因此很多人都会把左边的 option
和 command
的位置交换一下。这个可以通过 iterm2 的 Settings -> Keys -> Remap Modifiers
页面来设置,交换一下这两个键的位置。这样改动了之后,在 iterm2 中的所有涉及到 command
键的操作,就和 iterm2 外的不一样了。例如在 iterm2 中想切换窗口,按键是 option
+tab
(这里的 option
指的是物理按键的位置,因为我们的设置把 option
和 command
的位置交换了,所以实际的效果是 command
+tab
),然后切到其它窗口后再想切回 iterm2,要按的键位则是 command
+tab
。又因为 mac 神奇的窗口焦点行为,我经常会按错,需要先看下当前是不是在 iterm2 中,极大地降低了工作效率;但是如果不交换位置的话,按键又很难受。
其实我真正的需求是在 iterm2 中能够把 某些 command
的组合键映射为对应的 meta
的组合键,而并不是需要修改 option
的行为,或者 option
的位置。因此我最终使用了如下的解决方法。
例如 command
+f
,如果不做任何配置改动的话在 iterm2 中的行为是弹出查找框,但是我们期望的行为是在用 emacs 的时候能够往后跳一个单词。为了实现这个功能,我们在 iterm2 的 Settings -> Profiles -> Keys -> Key Mappings
中,新添加一个选项,Keyboard Shortcut
设置的是 command
+f
,Action
选的是 Send Hex Code
,在框里填入 0x1b 0x66
然后确认就可以了。其中 0x1b
是 Esc+
的十六进制代码,0x66
是 f
的十六进制 ASCII。
那怎么获得对应按键的 hex code 呢?例如这里的 command
+f
,可以在终端运行 xxd
,然后按 command
+f
,接着回车,接着 ctrl
+d
,会看到这样的输出:
$ xxd
^[f
00000000: 1b66 0a
其中第二行的 1b66
就是 command
+f
的 hex code,0a
就是回车的 hex code。添加完这项之后,在 iterm2 的命令行或者 emacs 中,按 command
+f
都会往后跳一个单词了。
如果需要映射其它按键的话,按照上面的方法一个个加就行,对于我来说这些映射并不多,所以也可以接受。下面是我的一些映射:
key | hex code |
---|---|
cmd+< | 0x1b 0x3c |
cmd+> | 0x1b 0x3e |
cmd+b | 0x1b 0x62 |
cmd+d | 0x1b 0x64 |
cmd+f | 0x1b 0x66 |
cmd+m | 0x1b 0x6d |
cmd+n | 0x1b 0x6e |
cmd+o | 0x1b 0x6f |
cmd+p | 0x1b 0x70 |
cmd+r | 0x1b 0x72 |
cmd+w | 0x1b 0x77 |
cmd+x | 0x1b 0x78 |
cmd+ctrl+b | 0x1b 0x02 |
cmd+ctrl+f | 0x1b 0x06 |
cmd+ctrl+k | 0x1b 0x0b |
cmd+ctrl+o | 0x1b 0x0f |
cmd+delete | 0x1b 0x7f |
其中 cmd+ctrl+o
是我自定义的一个按键组合,在 xxd
中不知道为啥不能正常显示,但是直接按 option+ctrl+o
能正常工作,也就是说 hex code 应该是存在的,只是通过 xxd
查不到。然后我观察了下 cmd+ctrl+f
的值(通过 xxd
获取的),发现 f
的 ASCII 是 0x66,加了 ctrl
之后变成 0x06 了,那 ctrl+o
会不会也是类似的 mask 呢?试了下果然就可以了。
最后要说的是,这个是在用 mac 键盘才会有键位的问题。如果用的是外接的非 mac 键盘,只要在 mac 全局交换 option
和 command
的位置(因为通常左 win
键对应左 option
键的位置,而左 Alt
键对应左 command
的位置,所以用外接非 mac 键盘我都会全局交换这两个键的位置),然后在 iterm2 中修改本文开头说的 Esc+
以及 key mapping,改完之后在 iterm2 中 command
就可以同时拥有 command
和 meta
的功能了。