7

Vim 里如何映射 CTRL-h 为 left ?

 3 years ago
source link: https://www.skywind.me/blog/archives/1857
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Vim 里如何映射 CTRL-h 为 left ?

很多人习惯在配置文件中映射 CTRL+HJKL 为光标移动,却碰到了一些问题:

inoremap <c-h> <left>
inoremap <c-j> <down>
inoremap <c-k> <up>
inoremap <c-l> <right>

映射后无效或者映射以后按 <BS>键不能删除,这是什么原因呢?

很简单,因为你的终端软件(Xshell, SecureCRT)有些老,默认配置是按下<BS>键以后
发送的是:^H (ASCII 码 0x08),而 ^H在你的 Vim 里被你 inoremap 成 了,所以你按了<BS>会被认为按下了左键。

早在 VT100终端时代,^H(ASCII码 0x08)表示<BS> 而 ^? (ASCII码 0x7f)表示<DEL>。过去 0x7f是留给 DELETE键使用的。而到了 VT220时代,DELETE已经变为 ^[[3~ (ASCII 码 0x1b, 0x5b, 0x33, 0x7e 共4个字节),而 ^? 的 0x7f 换给了我们的<BS>,有些老点版本的终端软件,默认 <BS>还是使用 VT100的 ^H,比如 Xshell 4 Build 0142以前的版本,默认<BS>是发送^H。SecureCRT直到6.x版本还在默认发送 VT100的 ^H。

你需要做的就是改一下终端默认配置而已,大部分不那么陈旧的终端软件,如今都是默认VT220的标准,比如 Xshell4 Build 0142及以后的 Xshell5,Putty,Mac下面的 Terminal.app, iTerm2,Ubuntu下面的 gnome-terminal,他们都是把 <BS> 发送成 ^?

你可以在你服务端下面查看下默认的键位设置:

$ stty -a

现在所有 Linux服务器的 erase (bs)基本都是 ^? 了(如果链接到非 Linux老操作系统 erase不是这个的话,需要改一下,可以在系统层改,也可以vim里面 set t_kb=…),Vim里面也是认可 ^?的,可老旧的终端软件却默认发送 ^H,不过好在他们都支持修改:

Xshell 老版本的修改方法

Properties -> Terminal -> Keyboard 里,把<BS>设置成 127,而 <DEL>设置成 VT220 Del

SecureCRT 6 的设置方法

Session Options -> Terminal -> Emulation -> Mapped Keys, 勾选 Backspace sends delete

Putty 设置方法

好像默认是 ^? 的不过需要到:Configuration -> Terminal -> Keyboard 下面下确认下 The Backspace key 是 Control-? (127)

Terminal.app

Mac 下面的 Terminal.app 默认是发送 ^? 的,你也可以到 Profiles Advanced 下面确认下 “Delete sends Control-H” 没有勾选。

iTerm2

iTerm2 下面默认也是发送 ^? 的,可以到 Profiles -> Keys下面确认一下 “Delete key sends ^H” 没有被勾选。

Gnome-Terminal

至于 Gnome-Terminal 和 MinTTY之流的默认是 ^? 要修改可以看具体文本配置文件。

好了,默认 Vim 同时识别 ^H(ASCII 码 0x08)和 ^?(ASCII码 0x7f) 都把这两个当成<BS>,现在我们统一把终端软件的 <BS>改为 0x7f以后,^H 的 0x08就空出来给我们 noremap了:

noremap <C-h> <left>
noremap <C-j> <down>
noremap <C-k> <up>
noremap <C-l> <right>
inoremap <C-h> <left>
inoremap <C-j> <down>
inoremap <C-k> <up>
inoremap <C-l> <right>
cnoremap <c-h> <left>
cnoremap <c-j> <down>
cnoremap <c-k> <up>
cnoremap <c-l> <right>

其实这样映射是有好处的,有时候就想在插入模式下移动一小下,真没必要 跳出。
命令模式下,这样移动也是有好处的,因为进场敲 Ex命令时都是按上,把上一条弄出来,移动下光标修改下,然后回车,这下 Ex命令模式下 直接 把上一条显示出来,然后 和左右移动修改。当然你也可以map成 emacs格式,为了保持一致性,Command/Normal/Insert/Visual我都做了这个设置。

可能你会问,NORMAL下面的 之类的不是覆盖给窗口移动 h 了么?这个看个人意愿了,比如你可以把你的窗口移动改为 h, j, k, l 四个键,向右移动窗口时normal下先按再按L,多顺畅?

如果担心覆盖了原生 的话,我们看看原生这几个键是做啥的。

:help index

上面这条命令会列出 Vim里面所有默认按键的含义,平时推荐多看看:

CTRL-H 同 `<BS>` 一样功能,我们都是直接用 `<BS>` 没人CTRL-H的,直接覆盖掉
CTRL-J 同回车(有两个码 0x0d 或 0x0a),C-J是0x0d,硬回车是0x0a,没人按这个,覆盖。
CTRL-K 输入 digraph,比如可以用来输入欧洲文字,不需要,实在需要可以把这个功能挪给 INSERT模式下的 CTRL-B (空闲),或者 <c-x><c-k> ,完全可以覆盖。
CTRL-L 重绘,很少用,自己可以把他挪到 <leader>r 之类的键去多干净,覆盖。

好了,看看上面这四个键基本都是些无关痛痒的功能,完全可以覆盖之。

当然,对于需要用 <C-K> 进行 digraph 输入符号或者日文的同学,推荐改为 <C-_> (其实是CTRL和减号一起按下):

inoremap <c-_> <c-k>

好了,因为本来 <C-_> 是用来处理从右向左的文字的(阿拉伯语,希伯来语,波斯语)我们不需要,所以覆盖之用来输入符号,原来输入 "<c-k>ko" 插入的是 “こ” ,现在改成了 "<c-_>ko" 而已。


相关阅读:Skywind Inside – Vim 中正确使用 Alt映射

1532 total views, 3 views today

I like thisUnlike Like2I dislike thisUndislike 

Categories: 随笔 Tags: Vim

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK