让Vim在图形界面与终端中的Alt组合键相同
source link: https://blog.lilydjwg.me/posts/23574.html
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在图形界面与终端中的Alt组合键相同
本文来自依云's Blog,转载请注明。
首先祝大家新年快乐!
一直都感觉Vim下快捷键不够用,于是在某一天,我开始使用Alt开头的组合键,然后发现了问题——
在很多终端中,Alt 组合键发送的是 Esc 前缀键码,而图形界面中则是置位最高位。举例来说,Alt-x在图形界面下向Vim发送的是ø
(在Vim插入模式下使用Ctrl-V Alt-x可以看到),其编码为0xf1
,而x的编码为0x78
,区别在于前者二进制编码的最高位是 1,而后者是 0。
而在gnome-terminal、konsole中则是另外一番景象。Alt-x和快速地按Esc x的效果是一样的,仅有xterm 和 rxvt 等终端可选地支持像图形界面的那样处理(参见Vim手册:help :map-alt-keys)。而且,使用置位最高位的终端将导致shell中的Alt-f之类的键绑定失效。
Emacs能处理这种不一致,但Vim不能,于是我一直是使用脚本,使得在终端下和图形界面下使用不同的键绑定。这样图形界面下没什么问题,但终端下比较郁闷:因为映射了Esc开头的键,而Esc是用于回到普通模式的,于是每次按Esc想退回到普通模式时都得等一秒('timeoutlen的值)。这个值又不能设小,不然\ww这种需要多次按键的映射就难用了。
前些天,偶然在帮助文档里看到了这个:
*:set-termcap* *E522* 需要 {option} 的地方,可以使用 "t_xx" 形式来设置终端选项。这些选项覆盖相应的 termcap 值。设置后,可以用于映射。如果 "xx" 包含特殊字符,须用 <t_xx> 形式: > :set <t_#4>=^[Ot 也可用来翻译普通键的特殊键码。例如,如果 Alt-b 产生 <esc>b,可用: > :set <m-b>=^[b (这里 ^[ 是真正的 <esc>,用 CTRL-V <esc> 来输入) 这个方法优于映射之处在于它能适用于所有情况。
也就是说,可以在终端下把Alt组合键都设置到Esc开头的键码,这样一是不用每次设置键映射时设置两个,更重要的是,其本质变了:这样的设置不是键映射,而是指定键码!这样会使用'ttimeoutlen'的值来等待后续键码,和映射无关了,我完全可以把它设置得很小。于是写出新的脚本:
1 " escalt.vim 控制台下让用 <M-x> 也可用 2 " Author: lilydjwg <lilydjwgATgmail.com> 3 " Last Change: 2010年12月15日 4 " ---------------------------------------------------------- 5 " Load Once: 6 if &cp || exists("g:loaded_escalt") || has("gui_running") 7 finish 8 endif 9 let s:keepcpo = &cpo 10 let g:loaded_escalt = 1 11 set cpo&vim 12 " ---------------------------------------------------------- 13 " Functions: 14 function Escalt_console() 15 for i in range(65, 90) + range(97, 122) 16 exe "set <M-".nr2char(i).">=\<Esc>".nr2char(i) 17 endfor 18 set ttimeoutlen=50 19 if &term =~ 'xterm' 20 set <F1>=^[OP 21 set <F2>=^[OQ 22 set <F3>=^[OR 23 set <F4>=^[OS 24 set <Home>=^[OH 25 set <End>=^[OF 26 endif 27 for i in ["", "c", "i", "x"] 28 exe i . "map Ï1;2P <S-F1>" 29 exe i . "map Ï1;2Q <S-F2>" 30 exe i . "map Ï1;2R <S-F3>" 31 exe i . "map Ï1;2S <S-F4>" 32 endfor 33 endfunction 34 " ---------------------------------------------------------- 35 " Call Functions: 36 call Escalt_console() 37 " ---------------------------------------------------------- 38 " Restoration And Modelines: 39 let &cpo= s:keepcpo 40 unlet s:keepcpo 41 " vim:fdm=expr:fde=getline(v\:lnum-1)=~'\\v"\\s*-{20,}'?'>1'\:1
注意到其中对于F1到F4等键进行了特殊的设置。没办法,这几个键特殊,这样设置我觉得是最优的解了。设置'ttybuiltin'也可以,但是经过一些时间的试用后发现有副作用,具体是什么我忘记了。
PS: SyntaxHighlighter 不支持 Vimscript,还好 Vim 有TOhtml
命令。
最新脚本在 GitHub 有。直接复制上面高亮过的代码是不行的。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK