之前换用 Vundle 管理Vim插件之后,我将自己使用的插件也顺便进行了一次大换血。
而这些插件中,最让人纠结的,当属和自动完成相关的插件了。
背景
之前,我给自己配置的是 ACP
,也就是大概挺久以前很热的 AutoComComplPop 。但是它的自动匹配仅限于针对上下文的一个索引的建立匹配单并在之后匹配单词而已,没有现在流传很广的 snippets
,所以也就没有十分强大的功能。
后来在配置 Vundle 的过程中,耳濡目染地就听说了现在使用的两个自动完成的插件:NeoComplCache 和 SnipMate。
之所以想要更换,除了是对新鲜事物的喜好之外,更多的也是希望能够用上他们的强大的自动完成功能。而说它们强大,简单来讲,是因为他们可以提供给Vim用户一种类似 TextMate
(Mac下的顶级编辑器,十分好用和强大)的体验。但是与此同时,要想获得强大功能和友好体验,作为一枚Vim插件,配置是在所难免的。而这两款的组合,配置起来却不是那么轻松的。
普遍情况
在一开始双方都是默认配置的情况下,问题其实就很明显了。由于两者都默认把功能键映射到了 <TAB>
,导致很多情况下任何一方会压制另一方,很有可能只能有其中一个产生效果。比如 NeoComplCache 的自动弹出匹配词,默认情况下我们应该是使用 <TAB>
来进行完成功能的,但是这个时候如果有适合的 snippets
,那么先发动的就是 SnipMate
,也就给你来个大段的代码段替换。这就和自己的意志想违背了,想做的都做不了。
于是考虑更改配置。一下两篇是唯一不多的介绍心得的文章:
从它们当中,可以发现,大家希望的功能其实是这样的:
1.不自动弹出匹配选项,当需要的时候用
<TAB>
来呼出选项框并可以用<TAB>
来选择;同时,如果恰好有snippets
匹配了,那么优先选择发动SnipMate
。
2.自动弹出匹配选项,用其他按键来完成选择;而<TAB>
仅仅用于SnipMate
。
1的话我们还需要 SuperTab
这个插件,但是个人感觉比较累赘,所以就选择了 方案2
.但是上述的文章2中的方案其实并不太合理。他利用 <SPACE>
来完成选项的选择,这样一来,每次匹配之后,都会自动再产生一个空格。
但是关键问题是,这个空格其实很多时候很多余。
我的方案
我的方案就是基于上述的 方案2
。我希望仅仅把 <TAB>
用于 SnipMate
的发动上,而用回车来选择匹配选项。这样的话,我们只需修改 NeoComplCache
的配置就可以了~(事实是 NeoComplCache 的配置在 vimrc
中,而 SnipMate 的配置则需要去它的源码中修改)
那么我该怎么做呢?参考2的配置,我的关键配置如下:
"<CR>: close popup and save indent.
inoremap <expr><CR> neocomplcache#smart_close_popup() . "\<CR>"
"<TAB>: completion. NO USE with snipmate
"inoremap <expr><TAB> pumvisible() ? "\<C-n>" : "\<TAB>" ********************
"<C-h>, <BS>: close popup and delete backword char.
inoremap <expr><C-h> neocomplcache#smart_close_popup()."\<C-h>"
inoremap <expr><BS> neocomplcache#smart_close_popup()."\<C-h>"
inoremap <expr><C-Y> neocomplcache#close_popup()
inoremap <expr><C-e> neocomplcache#cancel_popup()
"inoremap <expr><Enter> pumvisible() ? neocomplcache#close_popup()."\<C-n>" : "\<Enter>"
inoremap <expr><Enter> pumvisible() ? "\<C-Y>" : "\<Enter>" ********************
" 类似于AutoComplPop用法 .
let g:neocomplcache_enable_auto_select = 1
其中后面带有星号的两句话是关键。第一句,取消 <TAB>
的相关映射,第二句,赋予 <Enter>
<C-Y>
的功能。 <C-Y>
的功能是选择选项之后关闭弹出框。而我这么配置之后,同时也把回车键的换行效果取消了,免得选择之后光标却在下一行。
成效
配置之后,每次有匹配项,都会自动弹出选项,并且初始选择在第一个上,此时可以利用上下箭头或者 <C-P> <C-N>
来进行上下选择,并最终通过 <Enter>
来决定,之后无换行的困扰。而当我们觉得这时有 snippets
可以被匹配时,则按下 <TAB>
,大段代码段就替换完成了。
我很满意这个形式,虽然可能不是最完美的,但是目前来说是个比较方便且实用的方案了~