关于补全的方面要说的的确不少, 这里选择分为两个章叙述. 若是你想学vim, 你须要有很强的耐心, 若是你想锻炼这种耐心, 你能够试着先看完我以前的文章. 好了, 下面继续咱们的vim补全吧.php
vim补全1中曾经说起到supertab在更换版本后和UltiSnips成功共用tab的解决方案, 在此以前主要的叙述主要在作一件事情:将vim的tags补全和字典补全从supertab的补全功能中分离出来, 让supertab只负责一件事情:就近补全. 这样子作彷佛没有必要, 由于咱们彻底能够将他们所有放到supertab接管的tab键上来, 下面要说的就是为何咱们须要这样作.python
从最初的叙述中不难看出的想要实现最快最智能的补全的须要实现的几个功能:优秀的补全列表排列算法,可预见性的补全列表结果,高速的补全列表创建.优秀的补全算法这一点上其实vim也有比较好的插件, 从很早依赖与tags的Autocomplpop和omnicppcomplete到后来比较出名的neocomplcache,再到后来至关智能的YouCompleteMe,最后到我如今留下的clang_complete. 下面就一一看一下这些插件的特色. linux
首先是Autocomlpop和omnicppcomplete他们都是经过tags生成补全列表的,同时对tags的内容作过更加精确的分析能够实现诸如c++的一些类成员补全的高级功能. 不过因为tags文件自己的限制, 这种补全在实用性方面并非太好. 他们都是比较早的vim补全插件.c++
后来出现的一个neocomplcache插件比较出名, 网络上介绍他的文章不少. 主要的特色是经过在打开文件的时候一次性创建补全信息的缓存来提升补全速度. 这个插件我曾经使用过一段时间, 首先是打开文件的时候因为necocomplcache须要创建缓存, 若是文件比较大的话你将明显感受到卡顿. 现最新的neocomplcache 已经更名为neocomplete,新的neocomplete经过lua的支持解决了启动时创建缓存的过慢的问题. 固然他也须要更加高版本的vim的支持. 缓存一旦创建完成就比较快了. 补全列表几乎所有是瞬间弹出, 但是这么高的补全速度不见得是好事, 若是你设置了necomplcache的自动弹出功能. 你将发现,这个弹出功能在不少不须要弹出的地方依然工做, 因为弹出速度至关的快,不少时候你在快速的移动光标的时候他均可见缝插针的弹出补全, 这个么积极的补全最终让我选择了关闭他的自动补全. 在须要的时候经过按键触发. 这个触发键天然会被想到映射到tab键上, 网络上的确有这样作的实现方案. 很明显neocomplete是不能和supertab共存的. 这问题并非太过严重而且我曾经翻遍网络后在一个外文网站上找到了让neocomplcache和UltiSnips共存的方法. 但是最为严重的的问题是neocomplete和clang_complete冲突. 由于他们同时调用vim提升的全能补全函数接口. 调用同一个接口的结果是一个插件老是压制另外一个插件致使被压制插件彻底没有触发的能力.这种冲出彷佛彻底没有办法解决. 而clang_comlete又有不少我没法替代的优秀特性. 最终我仍是选择了放弃neocomplcache.git
关于YouCompleteMe就更加奇葩了, 首先是他没法和clang_complete,supertab,neocmplcache共存. 其次是他须要clang3.3的支持, ubuntu目前默认支持比较完整的clang3.0,这包括clang3.0相关的libclang库(这个库能够加快clang_complete的速度) 不知道是否是因为clang没到3.3的问题, 在我成功编译安装了YouCompleteMe以后clang支持的全部补全特性一个都没有出来过. 官方文档之说YouCompleteMe是支持UltiSnips的,在使用中我也发现补全列表中有UltiSnips触发关键字的身影,惋惜的是在选择这个些触发关键词以后简单的按enter键是没法展开UltiSnips的代码补全块的.百度后得出的解释是这里须要设置UltiSnips的展开键映射到<tab>键以外的其余键上并在补全列表中选择触发关键字以后经过这个从新映射的展开键来展开.惋惜, 我没倒腾到这一步就已经把YouCompleteMe卸载了, 由于他的clang特性在个人ubuntu12.04中始终没有成功过! 另外, 这个插件在编译以后居然达到了60M的大小!我其余vim配置加起来20M都不到, 真是佩服.,这么大的容量明显在编译YouCompleteMe的时候clang3.3是下载了的, 但是谁能告诉我, 为何clang的特性一个都没实现呢. 程序员
上面四个补全工具一一被淘汰以后, 最后剩下的惟一一个自动补全就是clang_complete了, 这是一个比较难控制的插件, 好在他和supertab以及UltiSnips并不冲突. 在ubuntu下使用clang_complete首先你须要下载clang编译器和libclang库. 下载命令以下:github
sudo apt-get install clang libclang1 libclang-dev算法
安装好clang编译器环境以后clang_complete就能够正常工做了.clang_complete主要实现了两个很重要的功能, 第一个是clang_complete能够动态的检测代码中语法错误, 这些语法错误是创建在clang编译器时时编译的结果的基础上的,所以至关准确. 其实clang_complete经过分析clang时时编译的结果实现比较高级的补全. 其中默认状况下clang_complete在". , ->和::"三个标识符后面自动触发. 这个这些标识符在C和C++中表明这指针的间接访问, 类对象成员变量和成员函数的调用等.这些地方的补全在简单的关键字检索方式很难实现精确的补全. clang_complete借助与calng编译器时时编译结果中的元素信息实现了这类补全的精确补全. 这个功能在补全C代码中的结构体, C++中的类对象时变得超级实用.数据库
clang_complete的配置选众多, 网络中有不少地方能够找到一些现成的配置.但这些配置大可能是相似的, 我按照网络上能找到的配置放在vimrc中之后发现vim变得不稳定. 首先是vim在某些状况下比较容易崩溃. 好比#include代码的中出现错误时就容易直接闪退. 又好比在写c代码时常常会收到vim被致命信号ABRT中断的问题. 很明显这些不稳定是clang_complete在clang后台时时编译代码后动态解析编译结果并将编译错误显示到vim的时候出现了没法解析的内容所致.这是一个严重的问题. 由于你不知道vim会何时崩溃, 崩溃后以前编写后没保存的代码将会丢失, 又一个坑字了得! 好在一天实在受不了clang的随时驾崩以后. 我开始查看clang的帮助文档. 在帮助文档的帮助下终于解决了这个问题.下面是关于calng_complete全局变量配置的一些意义和功能解说:编程
g:clang_complete-auto_select 该变量置1时,calng_complete在弹出补全列表以后会自动选择第一个选项但不会生效, 置2时自动选择首选项后同时将该项生效.
最初我将该变量设置为1, 后来发现这个选择彻底可使用默认的0, 由于在弹出补全列表以后你能够经过tab实现相同的效果.
g:clang_complete_copen 该变量控制语法错误检查后是否打开quickfix窗口列表. 默认值是0表示不打开. 若是你不想在编码时时不时看到quickfix窗口的弹出, 这里保持默认设置便可.
g:clang_hl_errors 该变量控制是否高亮显示clang检测到的语法错误, 这个功能至关实用. 默认值是1表示打开, 若是你但愿用到clang_complete的智能语法检测功能.这里保持默认设置便可.
g:clang_periodic_quickfix 这个变量是上面崩溃问题的关键, 网络上的配置为实现clang_complete对当前代码的时时语法检查, 这里大多将其设置成了1, 这个变量控制着是否认时刷新quickfix里的错误信息. 在该变量等于1时,只要咱们的光标在vim中保持三秒不动, clang_complete就会在后台给咱们刷新clang时时编译出来的结果. 这个功能的本意是好的. 但是clang_complete在刷新quickfix的时候彷佛对某些错误没法正确的解析, 这就致使了vim忽然的退出和致命错误提示. 很明显为了不vim忽然的退出致使的编辑内容丢失. 这里必定要保持默认设置.
g:clang_close_preview clang_complete在补全的时候默认是能够打开补全预览的,所谓的补全预览就是在vim的上面展开一个小的名为"草稿"窗口, 里面显示的是当前补全列表中选择内容的完整内容预览, 这个功能并不实用, 由于补全列表中的内容已经至关详细了, 忽然打开的草稿窗口只会给编辑带来不畅感.所以这里建议将其设置为1来关闭预览功能.
g:clang_snippets_engine clang_complete的补全带有必定的snippets功能, 所谓的snippets功能就是当补全内容是一个函数的时候clang_complete在补全确认后会首先定位到函数的第一个参数区并让用户修改, 修改完毕以后你能够经过回到普通模式(我这里经过`键返回普通模式)后使用tab键跳转到下一个变量区继续修改.clang_complete的说明文档中彷佛表示支持Ultisnips的snippets功能, 也就是若是咱们安装了UltiSnips并在这里将clang_snippets_engine设置成UltiSnips我就能够通<<vim之补全1>>中说起的ii和II来跳转可修改区. 惋惜的是我尝试过这里设置成UltiSnips结果是snippets功能紊乱. 最后仍是保持了默认的普通模式tab键跳转的方式. 好在这个方式仍是至关方便的.
g:clang_snippets 这个变量彷佛是用于开启clang_complete的snippets功能的, 而clang_complete的这个选择默认值是0,所以这里能够设置成1
g:clang_use_library 这个变量用于开启经过libclang库来加快clang_complete的反应速度. ubuntu在安装了libclang1 和 libclang-dev库以后就可以使用libclang库了. 因此这里明显是须要打开的.
g:clang_user_options 这一项用于对编译器的一些设置, C语言编辑下这里不须要设置, C++开发时能够在其中添加必要的参数.
g:clang_complete_macros 彷佛是用来补全宏什么的, 暂时不太清楚到底有啥做用, 将其设置为1暂时没有发现问题.
综合上面的描述, 最终咱们的对clang_complete的配置能够归结为一下几句话, 将其写到vimrc中便可:
"clang_complete插件设置
let g:clang_snippets=1
let g:clang_use_library=1
let g:clang_close_preview=1
let g:clang_complete_macros=1
"let g:clang_user_options='-stdlib=libc++ -std=c++11 -IIncludePath'
上面的设置咱们关闭了quickfix的定时更新功能. 这是为了防止vim意外崩溃而作的设置, 但是这也将致使clang_complete没法自动时时的显示语法错误了. 是否clang_complete提供给咱们的强悍的语法检查功能就没法使用了呢? 非也, 帮助文档中提到咱们能够经过手动调用函数的方式来触发quickfix的更新.也就是说任何说后咱们但愿看到clang时时编译以后的语法错误提示, 咱们只有手动调用这个函数便可. 固然,每次看个语法错误提示还要手动调用个函数当前不是个人风格. 经过将这个函数的调用捆绑在快捷键上是我惯用的伎俩, 但是捆绑在那个快捷键上好呢? 个人设计是和共用保存快捷键. 这样的共用设计实现了任什么时候候刷新quickfix内容以前文件老是被保存过了, 首先是这样的手动更新vim崩溃的可能性变得很小, 其次即使崩溃了,也不要紧, 由于咱们刚刚保存过! 在个人vimrc中保存用的快捷被映射到了alt+w上所以咱们只要添加下面的配置就能够实现保存和clang_complete语法检测共用alt+w组合的效果(为了防止在普通文件保存时触发ClangUpdateQuickFix函数而出现错误提示,这里配置成只在c和cpp类型的文件中触发该函数调用):
imap ^[w <esc>:call Smart_save()<cr>a
imap <a-w> <esc>:call Smart_save()<cr>a
nmap ^[w <esc>:call Smart_save()<cr>
nmap <a-w> <esc>:call Smart_save()<cr>
func! Smart_save()
exec "w"
if &filetype == 'c' || &filetype == 'cpp'
call g:ClangUpdateQuickFix()
endif
endfunc
注意其中的^[w 是经过在插入模式下先按下ctrl+v再按下alt+w产生的特殊字符,这种方式输入的alt+w是ubuntu的gnome-terminal终端惟一能识别的alt组合键的配置方法, 关于alt键的映射问题能够经过 :help map-alt-keys 和 :help map 以及 :help alt 来得到相关帮助.
和clang_complete相关的配置还有一个是
set completeopt=menu,longest 这是一个至关有效的设置. 这在后面的字典补全的地方会有说明,这里暂时就不作解释了.
最后要说起和calng_complete的相关的设置是项目根目录下.clang_complete文件. 这个文件是咱们手动创建的. 假设你当前编辑的项目源码中包含了一个本身定义的头文件,而这个头文件并再也不当前源文件所在的文件夹中而是在项目根目录的子目录include下面, 很明显,若是不告诉clang这个咱们本身的头文件的位置所在, clang在时时编译咱们的当前的源文件的时候将老是提示咱们的头文件找不到. 为了解决这个类问题, 咱们须要配置项目根目录的.clang_complete文件. 这个文件中能够设置全部和编译器相关的参数. 示例以下:
-w
-I include
-I lib/ipc
-I lib/unix
-I lib/net
-w 表示不对编译时的warning报错和高亮, 若是你但愿代码更加严重, 最好不要在这里加入-w, 若是你不想消除代码中的worning有不想每次查看语法错误的时候都看到这些worning被高亮, 那么能够在这里添加-w
-I 后面跟的是目录名表示告诉编译器到那里去找到咱们本身定义的头文件.
clang_complete补全对应着优秀的补全必要特性中的高级算法. 另外一个必要特性是可碰见性的补全结果.这个特性主要是为了提升补全的命中率和盲补的可能性. 在VAX中因为算法比较复杂, 补全的可预见性也被算法接管, 但vim中就不是这样了, 由于vim没有这么智能. 虽然和其余的IDE相比vim在补全的智能程度上的确有所不及.可是真所谓笨鸟先飞, 傻人有傻福.(^_^). vim的做者在设计vim的时候很明显也意识到了这一点, 既然程序自己不能作到高度的智能, 那么咱们就须要将一部分须要智能区分的工做交给用户, 要知道人永远要比计算机更加的智能. vim为此设计了多达15种补全模式, 为的就是将不一样场景中的补全分开而且将触发各类补全的时机交给用户, 也就是但愿用户能够智能的先过滤到一部分彻底没必要要的补全来达到提升补全精度的目的. 这十种补全中咱们须要关注的只有几个, 下面要说的就是最后要上场的四个vim自带的补全配置, 这些补全在<<vim之补全1>>中最开始就提到过. 首先要说的是tags补全, 因为tags补全对项目中不在上下文和buffer中的关键字补全行之有效而且tags补全大多时候是能够预测的(可预测指到在咱们知道何时时候后须要触发的tags补全). 所以, 咱们有必要将其保留, tags补全分析到这里最后须要考虑的就是怎么能更加简单的调用它. vim大多数捕全面是经过ctrl+x加上另外一组ctrl组合键触发, 没调用一次补全须要按四个键, 很明显这是不合适的. 为此,咱们须要想出更好的调用方式. 不过, 在思考这个问题以前咱们须要解决另外一个更加棘手的问题: 不知道是否是插件冲突的问题, 在我根据上面的表述将supertab和UltiSnips成功的共存以后, 出现了一个严重的问题: 在插入模式下输入ctrl+x组合键的时候, vim会自动输入下面的字段:
=<SNR>53_ManualCompletionEnter(
)
很明显这是某个地方映射了ctrl+x键而且没有正确执行的结果. 定位的咱们安装的supertab.vim文件中, 搜索<c-x>, 很快728行(你可能不在这一行).找到了以下代码:
imap <c-x> <c-r>=<SID>ManualCompletionEnter()<cr>
在这一行的开头添加"将其注释掉, 清除全部.vim/view目下的全部记录, 打开文件从新输入<ctrl+x><ctrl+]>, tags补全成功被调出.
supertab的映射问题解决以后咱们能够继续考虑上面的需求. 咱们须要尽可能用最少和最容易操做的按键来触发补全的调用.补全的触发键首先是ctrl和alt组合键不能用, 由于在个人<<vim之快速跳转>>中有说起,ctrl的组合键首先是有一部分被vim默认占用后不可从新映射, 另有一部分如组合键直接不能实现映射. 其余能用的ctrl组合键大多用于实现vim的跳转和定位. alt组合键在操做上并不流畅,比较适合作操做并不频繁的各类功能映射. 其次, 补全的触发键必须在插入模式直接触发, 这样
又致使这里的映射不能像普通模式那样经过单键来实现.
ctrl,alt,单键都不能作映射, 难道补全就不能实现更好的重映射了吗? 非也, 以前提过vim有一个神奇的双键映射功能. 因为vim有一个按键等待模式, 所以即使的实在插入模式下双键映射依然能够很好的工做, 好比咱们的在插入模式下用jj作映射,任什么时候候咱们在插入模式下快速的输入jj键均可以触发这个映射. 你可能会问题, 这样一来我不是不能输入连续的两个jj了吗?非也, vim对全部的用户输入若是在功能上没法是未决的, 那么vim会进入输入等待模式,这个等待时间默认是1秒, 在你输入一个字符后的1妙内,vim会等待你输入第二个字符来肯定输入的功能. 若是在这一秒内你没有输入第二个字符来触发某个映射.那么vim就会认为你是但愿单纯的输入第一个字符. 所以在1秒后你的字符会转换为正常的字符并上屏.这样一来, 若是咱们对jj作了映射, 咱们有但愿输入两个连续的jj的话就很容易实现了, 咱们只要在输入第一个j以后等待大约1妙再输入下一个j就能够了.若是你不了vim多字符映射功能, 那么你极可能会为在某天你从别人那借鉴了某些设置以后发现本身vim的输入变得莫名奇妙的卡顿了.实际上这种卡顿在大多数状况下是不会影响咱们正常编辑的, 只要咱们编辑的的内容没有和双字映射重叠, 咱们大可没必要理会这样的停顿, 你的编码速度有多快就写多快吧.放心, vim会跟上你的编辑速度的. 固然这里在作双键映射的时候也不能作任意的组合, 某些在你编码或编辑中出现频率很高度组合是不适合作双字映射的.好比方便又按的"ll"就不适合编程的人用来作映射."ll"在不少很经常使用的的单词中出现(malloc是最多的一个),所以若是你用他来的作映射,那么你不得不在每次输入malloc的都时候都要停顿一次,而且这种停顿每每被咱们一鼓作气的打出一个malloc所误伤! 第二个双字映射须要注意的是要尽可能使用那些尽可能容易操做的组合, "jj"组合要远比"pp"组合好按的多. 最后一个须要注意的时候最好只用几个特定的按键来产生各类不一样的组合来的映射.由于只要一个按键在你的vim配置中有一个相关开头的映射, 咱们在任什么时候候输入这个按键都会看到卡顿现象. 若是你把键盘上的26个字母和其余字符全用双字映射了一遍, 那么每一个按键在任什么时候候按下的时候都会被卡顿. 我想应该不会有人会喜欢中样的输入体验的.综合上面的叙述, 个人双字映射中大多用到了"jkl"和"JKL"这六个字符作组合映射. 这里我挑选了至关好按键的"kk"来作为tags补全的触发映射.
你可能会说"jj"键比"kk"键更加易于操做, 为何不用它来作为tags补全的映射呢? 答案是咱们还有一个比tags补全使用更加频繁有效的补全方式, 那就是字典补全! 这个补全在vim中的默认触发键是<ctrl+x><ctrl+k>, 在我以前叙述中屡次提到过字典补全, 可见他的功效之高, 首先说明字典补全的原理:咱们在一个任意名字的文件中用空格作为关键词写下多个词组, 这些词组是咱们但愿用于补全的词组. 在.vimrc经过下面的方式告诉vim咱们的字典在哪里:
set dictionary+=~/.vim/tab/C.dic
我将全部的我的补全字典所有放在了~/.vim/tab目录下, 出了用于c语言补全的C.dic还有针对c++的cpp.dic和针对于网络编程开发net.dic等等, 这些字典完事是咱们本身设计的所以字典的名称,字典内容以及字典的分类方式彻底取决于咱们我的. 若是咱们用c语言的同时还须要使用网络方面的开发接口, 这里能够在vimrc继续添加以下内容:
set dictionary+=~/.vim/tab/net.dic
字典在路径指定给vim以后插入模式下任什么时候候咱们经过<ctrl+x><ctrl+k>触发字典补全,vim都会按照vimrc中添加的顺序来检索全部存在的字典文件. 单个文件中vim的检索顺序是从文件头顺序到文件尾.
字典补全的原理是很简单的, 第一次看到你可能会以为字典补全没有什么特别,也没什么强大的地方. 不过下面对字典补全优势的分析可能会让你改变这个见解.首先, 字典补全的字典是咱们本身设计的, 这将给予咱们的是最为灵活的补全列表定制功能. 使用vim的人大可能是程序员, 而程序员使用的语言有不少, 也许你和我同样是一个普通的c语言的使用者. 也可能你是一个php工程师或着使用python作开发. 不管你是用什么语言, 字典补全老是可用的. 由于你php的工程师彻底能够本身定制一个php.dic供本身使用.其次字典补全可让步补全的精度提到很是高的一个高度. 如今假设你和我同样都是C语言程序员, 但个人开发主要是作网络信息采集和处理, 而你的开发是用c语言来写驱动程序.这么一来即使咱们用的是彻底相同的语言, 个人C.dic也可能和你的c字典大不相同, 由于我可能永远不会用到驱动程序里的接口函数, 你也可能彻底无论任何应用开发使用的函数.补全字典能够作到补全列表的高度定制化, 任何你用不到的关键词均可以被你排除在外, 等到哪天你须要用到它时, 再添加和修改字典补全也是很容易的. 这种彻底按需求的定制字典能够保证补全列表中基本没有冗余的内容. 第三个补全字典的优势是便于切换,这在以前已经提到, 咱们彻底能够定制补全种类的字典的在不一样场合单独或组合使用. 字典补全的第四个优势是补全的结果是可预测的. 这个特性至关的实用, 由于它可让字典补全实现盲补(我本身发明的词, 在<<vim之补全1>>中有说起). 盲补就像盲打同样是全部补全中最快的一个, vim在检索补全字典中的内容时老是按照从头至尾的顺序扫描并排列结果的. 一来只要字典中的关键词顺序没有变. 补全出来的结果也不会变, 二来咱们任什么时候候均可以经过修改补全字典中关键字的内容和顺序来让补全列表的结果变得更加合理高效.字典补全最适合用于各类编程语言或普通编辑中那些不变的语法关键词, 这些语法类的关键词首先是固定不变的, 其次是高频率的出现. 好比C语言中语法关键子struct这个关键词出现的频率至关的高, 若是咱们使用就近补全或者是tags补全等其余方式的话, 补全列表的结果会因上下文内容的变化而产生化, 这样咱们不得不在每次的触发中下意识的去查找.而字典补全则彻底不一样, 若是你吧sturct在C.dic中放置在很是靠前的地方, 那么你将可以肯定每次经过s触发字典补全的时候首选词老是struct, 这样就实现了盲补的特色. 字典补全的最后一个优势是对一些有规律的很长的带有体系特色而且每每很长的接口函数和接口关键词的的补补全行之有效.下面是个人C.dic中关于linux线程的字典记录:
pthread_t
pthread_create() pthread_exit()
pthread_keycreate() pthread_keydelete()
pthread_join() pthread_self()
pthread_setpecific() pthread_getspecific()
pthread_cleanup_push() pthread_cancel()
pthread_detach() pthread_equal()
pthread_attr_t
pthread_attr_default() pthread_attr_init()
pthread_attr_getschedparam() pthread_attr_setcheparam()
pthread_attr_setscope() pthread_attr_setdetachstate()
PTHREAD_
PTHREAD_CANCELED
PTHREAD_PROCESS_
PTHREAD_PROCESS_PRIVATE PTHREAD_PROCESS_SHARED
PTHREAD_SCOPE_
PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_PROSESS
PTHREAD_CREATE_
PTHREAD_CREATE_DETACHED PTHREAD_CREATE_JOINABLE
cond_attr
pthread_cond_
pthread_cond_init() pthread_cond_destroy()
pthread_cond_broadcast() pthread_cond_singal()
pthread_cond_timewait() pthread_cond_wait()
pthread_delay_t
pthread_delay_np()
pthread_mutex_t
pthread_mutex_init() pthread_mutex_destroy()
pthread_mutex_lock() pthread_mutex_unlock()
pthread_mutex_mutex() pthread_mutex_trylock()
pthread_mutexattr_setptype() pthread_mutexattr_setpshared()
pthread_mutexattr_init() pthread_mutexattr_destroy()
PTHREAD_MUTEX_
PTHREAD_MUTEX_NORMAL PTHREAD_MUTEX_ERRORCHECK
PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_DEFAULT
PTHREAD_MUTEX_INITIALIZER
sched_param {
sched_priority
}
sched_
pthread_once_t
PTHREAD_ONCE_INIT
这个不怎完善的线程接口字典有不少规律性的特色 他们大多以pthread_和PTHREAD_开头后面每每还有一些子字段,它们中大多数比较长而显得不那么友好, 若是你老是一个一个去打的话,即使利用就近补全只打首次, 你也会以为很麻烦. 这里利用字典补全当咱们利用字典补全在任什么时候候经过pth触发, 出如今补全列表首的将会是pthread_这个开头总会是正确的, 咱们在他的后面再加上一些子字段的关键字继续补全就会将补全精肯定位到咱们须要的结果上.这个补全至关的好用.
你可能会以为制做这个补全字典比较麻烦, 首先是你能够在感受到某个高频词须要加入字典的时候将其添加进来. 你也能够在看相关书籍的时候做为一种总结性的笔记边看边把他们加入到字典. 这种方法比较系统, 也能够帮助咱们学习. 总之, 这些字典是日月累起来的分散到零散的工做时间中去以后, 你会发现制做他们基本上没有额外的时间开销.
在个人vimrc中利用"jj"这个双字映射中算是最容易操做的映射来触发字典补全, 另外还设置了"JJ"来触发路径补全. "JK"来触发头文件补全(在<<vim之快算跳转>>中曾经把"jj"和"kk"用于上下移动, 这里更新为补全触发. 因为在编码中从成对的标点最后右移跳出标点的操做至关的频繁,所以保留了"jk"右移和"kj"左移的功能). 综上所述, 下面给个人vimrc相关映射配置片断:
imap kj <left>
imap jk <right>
imap jj <c-x><c-k>
imap kk <c-x><c-]>
imap JJ <c-x><c-f>
imap JK <c-x><c-i>
vim补全相关的内容最后还有一个小小问题须要讨论一下, 这个问题是vimrc中completeopt的设置带来的. 首先是completeopt用于控制补全列表的显示方式, 主要是三个, menu方式表示展开补全列表, longset方式表示在补全列表中存在公共的最长字串时将其直接上屏, preview表示打开预览窗口. 第一个menu通常是必选的, 第三个preview由于没有多少苦实质的用处,使用后反而会在的补全不时的给你在窗口上方弹出个"草稿"窗口而打乱了咱们输入节奏, 所以建议不要使用. 问题出在第二个longest上面, 这是一个比较纠结的补全显示方式, 他的优势是,若是你输入向上面拥有公共字串的pthred_类型的补全时, longset开启以后pthread_会在
你触发补全时就上屏, 而且因为这时没有选择任何一个补全列表中选项, 所以当咱们继续输入以后子字段时补全列表会很天然的更新到更加精确的补全列表上来. 若是longset关闭, 那么触发后会默认选择第一个选项, 若是上面的列表中第一个词pthread_t修改成pthread_ 那么会在出现pthread_以后很天然的继续输入mu等来继续精确选择诸如pthread_mutix_init的选择但是问题出在继续输入mu等子字段后补全列表会自动关闭, 咱们必须经过再次使用"jj"来从新弹出补全列表. 这个样每一个具备子字段的补全必须使用至少四个j才输入完毕. 这在输入上彻底没有longest开启时那么天然. 但是若是真的设置longest方式, 若是咱们输入诸如struct这样
彻底没有公共字符串的单词时又会变得麻烦, 由于他不会默认给你选择补全列表中的第一个选项. 这在输入时又变得的不那么天然了, 这么一折腾longest变得至关蛋疼. 开也不是, 关也不是. 这个问题我酷似冥想了好几天无果...以后只想出了一个能够稍微方便一点的办法就是将上面字典中ptheard_这样的公共字串写成pthread_t这样的多一个单词的关键词而且关闭longest, 这样一来在输入pth触发字典补全以后会选中第一选项pthread_t, 若是咱们想输入phread_mutix_init就先删除一个单词t, 这个时候补全列表上不会选择任何一个选项, 以后当咱们再输入mu时补全列表是不会关闭的, 咱们就能够省去一次"jj"的触发输入. 固然, 这种输入只能稍微的让补全变得更加平滑一点, 并非解决的根本办法. 若是那位读者有更好的解决办法但愿能够给予回复或发邮件告诉我, 我的将不甚感激.
个人邮箱以下:pangchol@163.com
好了, vim补全相关的内容我暂时就研究到这里, 终于写完了, 最后来作一个总结:
咱们拥有本身的补全字典, 在写项目代码时首先在vimrc指定正确的补全字典. 将前辈的代码和本身的函数库等加入本身的项目中. 利用f12键随时创建或更新tags和cscope. 咱们须要最学会UltiSnips的代码块补全定制方式, 在必要的时候修改~/.vim/vunder/UltiSnips/UltiSnips目录下相关的代码块补全模板来定制符合项目和我的需求的代码块补全. 咱们须要认真定制和记忆这些代码块补全的触发关键词, 在任什么时候候均可以经过输入这些触发关键词后输入Tab键来触发代码块补全功能. 任什么时候候若是须要补全一个上下文或其余打开的缓冲区中出现过的单词, 咱们均可以经过Tab键触发就近补全(只要注意不要输入了和代码块补全触发关键词相同的内容来触发便可). 这个单词在上下文中离光标越近越容易实现盲补.若是一个函数或者变量名等存在于前辈的代码或者函数库中, 咱们能够经过"kk"键来触发tags补全来比较精确的找到他们. 任什么时候候若是你想输入语法中的关键字或者编程语言中的标准库接口等均可以经过"jj"来触发字典补全(已经定制好的)高速而精确的实现,标准接口函数名每每在第一次使用时经过字典补全触发,以后大多使用就近补全更加快速高效. 而数量很少词组简单但又出现频率极高的语法关键字(诸如: struct static等)咱们最好老是采用字典补全, 认真设计你补全字典尽可能保证越高频的语法关键在字典补全的越前面. 你将发现发多时候你输入他们都是在盲补!若是你须要输入系统中的路径你能够试着使用"JJ"触发路径补全. 若是你肯定一个关键子存在于当前文件包含的某个头文件中, 你也能够试着经过"JK"来触发头文件补全. 最后, 任什么时候候clang能够支持时时编译的编程语言中(C,C++,object-c等), 在咱们输入".","->","::"后clang_complete会自动经过clang的编译分析来获得补全精度至关高的结构体成员或类成员的补全.若是咱们但愿查看一下当前编辑的程序有没有语法错误,你也使用alt+w来保存后自定触发clang_complete的语法错误分析和高亮功能,clang_complete的语法错误高亮功能只在类型为c或cpp的文件中被触发.
后记:
2013-1214
最近几天在使用vim跳转的时候发现ctrl+]的跳转有些诡异, 不少时候都不会跳转的关键字的定义上. ctrl+]在默认状况下被用做ctags三跳转. 经过:h CTRL+]查看相关的帮助文档才知道ctrl+鼠标左键和ctrl+]的功能相同ctrl+鼠标右键和ctrl+t的功能相同(哎, vim到底还有多少好东西我尚未知道呢?), 这时再测试ctrl+左键的跳转, 诡异的现象出现了, ctrl+左键居然和ctrl+]的跳转结果不相同! 我来个去, vim帮助文档写错了?? 仔细想了想帮助文档应该不会有错, 这样可能的问题应该是ctrl+]被某个插件替换了. 想一想本身的全部插件中能够实现跳转的功能的除了cscope就是剩下clang_complete了, cscope以前没有问题, 因此目标首先锁定在clang_complete上, 经过:h clang_complete查看它的帮助文档后缘由就找到了, clang_complete默认将ctrl+]和ctrl+t做为跳转到声明的快捷映射了. ctrl+]原本的功能是跳转到定义! 缘由找到以后就很容易解决了, 在vimrc添加若是内容将clang_complete的跳转映射修改到不用的键位上(键盘上的映射组合都快用完了, 想再找一个好用的快捷键不容易啊, 最后只能用ctrl+P和ctrl+T了):
let g:clang_jumpto_back_key="<C-T>"
let g:clang_jumpto_declaration_key="<C-P>"
这样映射以后, ctrl+]将保持原有的经过tags跳转到定义位置的功能. 若是cscope存在的状况下,vim的ctrl+]默认会先搜索cscope中的数据库.在定义跳转上tags的跳转要比cscope准确一点(tags几乎用做定义跳转). 为了上vim的ctrl+]默认先搜索tags文件. 咱们须要在vimrc添加以下配置:
set nocst
咱们能够在vimrc添加专门用于cscope的定义跳转映射以便在ctrl+]跳转失败的状况下使用cscope试试.关于这方面的讨论, 更具体的内容能够在个人<<vim之tags>>中找到.
若是鼠标就在身边, 其实ctrl+鼠标左键和ctrl+鼠标右键的组合要比ctrl+]和ctrl+t更加方便一点.
若是你真的须要跳转的一个关键字声明的地方能够通ctrl+P(注意是大写的P)来实现. ctrl+t 和ctrl+T均可以实现递归的跳回到以前位置的功能.
在此次ctrl+]功能修正的过程当中还发现了一个坑爹的问题, 好久以前我就发现vim中有些快捷键组合是绝对不能用来作映射, 若是用了后果就是vim完全凌乱. 这样的组合键典型例子有: ctrl+[, alt+[, alt+] . 一直以来知道的他们不能使用, 但具体缘由并不明了. 今天在配置ctrl+]的时候意外的留意到vim若是直接输入ctrl+[ 输入提示中出现的^[符号, 而这个^[符号是特殊的组合键的转译起始字符而且<esc>键也被vim看成^[来处理. 同时alt键的组合键因为在gnome-terminal中会转译成<esc>开头的特殊组合键,所以又会用^[来代替, 我来个去, 这么多的键位重合, vim不凌乱才怪哦...
2013-1216
这几天使用vim发现即使经过alt+w来在保存以后调用ClangUpdateQuickFix()函数来手动触发语法错误检测. vim仍是出现频繁崩溃的问题. 实在受不了了只能再次求助百度谷歌. 在网上海搜了一翻以后在clang_complete做者的github上找到了一些相关的问题讨论. 不过惋惜的是没有找到具体的解决方法. 仔细观察讨论的内容发现彷佛最新的clang_complete修复了很多容易崩溃的问题. 在看看本身vimrc中vunder对clang_complete的下载源设置:
Bunder 'vim-scripts/clang_complete'
vim-scripts在github上是一个专门存放vim.org下插件拷贝镜像的地方, 也就是指我当前的clang_complete是发布在vim.org上的最后的一个版本. 仔细看看clang_complete做者的github发如今Rip-Rip/clang_complete目录下,也就是指这里的版本可能要比vim.org上最新的版本要新. 因而将上面的源配置修改成:
Bundle 'Rip-Rip/clang_complete'
从新清理和更新了clang_complete以后崩溃的问题暂时尚未遇到了, 但愿的真的是版本的问题吧.
最后在做者git的讨论中彷佛还看到若是开启libclang功能会致使崩溃的可能增长. 所以将 let g:clang_use_library=1 这句删除来关闭libclang的使用可能会好一点, 我暂时没有关闭, 先用着观察一段时间吧.
2014-0105
通过较长时间的测试这里得出的最新结论是clang_complete的语法错误高亮功能的确很是容易致使vim的忽然崩溃, 最近终于绝对将这个功能完全从vim的经常使用功能中剔除, 保持他的默认关闭,而且分配一个不适很好用的快捷键给它. 如今想一想其实代码的语法错误检查功能并非一个很是必要的功能, 由于在编码的过程当中语法错误几乎是没法避免的, 编码时不关注这些临时的语法错误其实不会下降编码效率. 如今vimrc中和clang_compelte相关的设置若是以下(关闭的libclang支持和自动语法检测):
"clang_complete
let g:clang_snippets=1
let g:clang_close_preview=1
let g:clang_complete_macros=1
"避免和ctrl+],ctrl+t原有的功能冲突
let g:clang_jumpto_back_key="<a-t>"
let g:clang_jumpto_declaration_key="<a-d>"
ino <a-s> <esc>:call Show_error()<cr>a
nno <a-s> <esc>:call Show_error()<cr>
func! Show_error() wall if &filetype == 'c' || &filetype == 'cpp' call g:ClangUpdateQuickFix() endifendfunc