在上一篇博文 Vim配置之入门篇中,只是大略介绍了 Vim 的基本配置以及几个常用的使用插件,但是在后面的使用中发现该配置的Vim并不是很好用,特别是 minibuffer,taglist,fileexplore 直接存在冲突,而且它的插件管理也比较麻烦。本篇博文主要就是解决这两个问题以及尝试一些更适合码农的插件。
简介
之前使用 Vim 的初衷一方面是其插件的强大,更主要的方面是适合装 13 。但是随着对 Vim 更多的了解,才发现Vim的强大还是有缘由的,从下面的评价足以看出:
- 世界上只有三种编辑器,EMACS、VIM和其它
- VIM is the God of editors, EMACS is God’s editor
- EMACS is actually an OS which pretends to be an editor
根据上篇博文中的配置在日常使用的出现的问题,在此给出解决方案,对于插件间的冲突问题是用 tagbar 取代 taglist,而插件管理是采用 bundle 插件。对于 Vim 里面实用方便的插件的确有不少。
高效插件
vim的插件很多,而且功能很强大,非常强大。官网的插件地址在 这里。
vundle
vundle是个用来管理vim插件的插件,它高效的利用了git,使得vim插件的安装,更新和卸载都交由vundle管理,从而将使用者从vim安装配置中解放出来。
安装vundle
1git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle
使用 vundle 管理 Vim 插件
在 Vim Script 选好想要使用的插件
在 Vim 配置文件 .vimrc 中添加
Plugin plugin_name
执行 vundle 初始化命令
:PluginInstall
,插件就安装好了常用命令
1# 更新插件 2:PluginInstall! 3# 清除不再使用的插件 4:PluginClean 5# 列出所有插件 6:PluginList 7# 查找插件 8:PluginSearch
vundle在.vimrc中的配置
1" 文件类型检测关闭[必须](/usr/share/vim/vim74/filetype.vim) 2filetype off 3" 设置runtime path包含Vundle的路径并且初始化 4set rtp+=~/.vim/bundle/Vundle.vim 5" 设置plugins安装地址 6call vundle#begin('~/.vim/bundle/') 7" 安装Vundle,让其管理插件[必须] 8Plugin 'gmarik/Vundle.vim' 9 10"""""""""""""""""""""""""""""""""" 11" Vundle插件安装样例: 12" 插件在github上 13" Plugin 'tpope/vim-fugitive' 14" 插件来自网页http://vim-scripts.org/vim/scripts.html 15" Plugin 'L9' 16" Git插件,但插件不在Github上 17" Plugin 'git://git.wincent.com/command-t.git' 18" 插件在本地机器上 (i.e. when working on your own plugin) 19" Plugin 'file:///home/gmarik/path/to/plugin' 20" The sparkup vim script is in a subdirectory of this repo called vim. 21" Pass the path to set the runtimepath properly. 22" Plugin 'rstacruz/sparkup', {'rtp': 'vim/'} 23" 使用用户名来避免插件冲突 ie. L9 24" Plugin 'user/L9', {'name': 'newL9'} 25"""""""""""""""""""""""""""""""""" 26 27" 所有插件的添加在end之前[必须] 28call vundle#end() 29" 文件类型对应的插件[必须](/usr/share/vim/vim74/ftplugin.vim) 30filetype plugin on 31" 文件类型对应的缩进文件 32filetype indent on
The-NERD-tree
NERDTree 是 Vim 最常用的插件之一,可以在 Vim 运行时显示目录和文件结构,类似 TextMate 左侧的文件浏览器,但操作起来更为方便,你可以在手不离开键盘的情况下快速浏览文件,并在文件和文件夹之间进行切换。其样例如下图所示:
在vim中的安装和配置
1call vundle#begin('~/.vim/bundle') 2" 在Vim的编辑窗口中树状显示文件目录[The-NERD-tree] 3Plugin 'The-NERD-tree' 4call vundle#end() 5 6"""""""""""""""""""""""""""""""""" 7" The-NERD-tree配置 8"""""""""""""""""""""""""""""""""" 9" 不显示缓冲文件,中间文件 10let NERDTreeIgnore=[ '.pyc$', '.pyo$', '.obj$', '.o$', '.so$', '.egg$', '^.git$', '^.svn$', '^.hg$' ] 11" 只剩一个NERDTree窗口时退出vim 12autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") &&b:NERDTreeType == "primary") | q | endif 13" <F9>打开/关闭文件管理器 14nnoremap <silent> <F9> :NERDTreeToggle<CR>
The-NERD-Commenter
这个插件也是必备的,主要自动注释内容。当你 xml 自然是 xml 注释,当你是 java 自然就是 java 的注释规则。其样例如下图所示:
在 Vim 中的安装和配置
1call vundle#begin('~/.vim/bundle/') 2" 快速添加/去除注释 3Plugin 'The-NERD-Commenter' 4call vundle#end() 5 6"""""""""""""""""""""""""""""""""" 7" The-NERD-Commenter配置 8"""""""""""""""""""""""""""""""""" 9" 注释的时候自动加个空格, 强迫症必配 10let g:NERDSpaceDelims=1 11" mm智能判断加上/解开注释 12map mm <leader>c<space>
ctrlp
这是个文件查找的插件,其功能和 NERDTree 有点类似,但是还是有点区别吧。其样例如下图所示:
在vim中的安装和配置
1call vundle#begin('~/.vim/bundle/') 2" 文件搜索 3Plugin 'kien/ctrlp.vim' 4call vundle#end() 5 6"""""""""""""""""""""""""""""""""" 7" ctrlp配置 8"""""""""""""""""""""""""""""""""" 9" 设置CtrlP的本地工作目录,0代表不设置该功能 10let g:ctrlp_working_path_mode=0 11" ctrlp窗口在底部 12let g:ctrlp_match_window_bottom=1 13" ctrlp窗口最大高度为15行 14let g:ctrlp_max_height=15 15" 窗口 16let g:ctrlp_match_window_reversed=0 17" 最近打开的文件的个数 18let g:ctrlp_mruf_max=500 19" 记录但去掉重复的软链接 20let g:ctrlp_follow_symlinks=1 21" <Ctrl-f>启动文件查找 22let g:ctrlp_map = '<c-f>' 23" Ctrlp启动文件查找 24let g:ctrlp_cmd = 'CtrlP' 25" 相当于mru功能,show recently opened files 26map <c-p> :CtrlPMRU<CR> 27" 忽略以下文件类型 28set wildignore+=*/tmp/*,*.so,*.swp,*.zip 29" 忽略以下文件目录 30let g:ctrlp_custom_ignore = {'dir': '/].(git|hg|svn|rvm)$','file': '(exe|so|dll|zip|tar|tar.gz)$'}
ctags
ctags 可以建立源码树的标签索引(标签就是一个标识符被定义的地方,如函数定义),使程序员在编程时能迅速定位函数、变量、宏定义等位置去查看原形。
安装 exuberant-ctags 工具
1sudo apt-get install exuberant-ctags
创建 C++ 代码库索引
下载 libstdc++ 头文件,包含 C++ 中 STL,streams 等。
解压到 ~/.vim/tags 目录后执行 ctags 命令
1ctags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ cpp_src 2mv tags ~/.vim/tags/cpptag
在.vimrc中设置
1set tags+=~/.vim/tags/cpptag
创建 Gcc 代码库索引
ubuntu中安装完build-essential后,会在/usr/include/c++目录下有C/C++的头文件。
1sudo apt-get install build-essential
拷贝/usr/include/c++/4.8里的文件到~/.vim/tags/gcc文件夹里后执行ctags命令
1cp -R /usr/include/c++/4.8 ~/.vim/tags/gcc 2ctags -R --c++-kinds=+p --fields=+iaS --extra=+q gcc 3mv tags ~/.vim/tags/gcctag
在.vimrc中设置
1set tags+=~/.vim/tags/gcctag
cscope
Cscope,一个应用程序,程式员使用它来协助程式撰写及追踪程式码,主要使用于C语言程式。最早起源于贝尔实验室,运作在 PDP-11 上,由 Joe Steffen 开始发展。
安装 cscope 工具
1sudo apt-get install cscope
创建gnu c库索引
下载 glibc 文件,它是 GNU 发布的 libc 库,即 C 运行库。glibc 是 linux 系统中最底层的 api,几乎其它任何运行库都会依赖于 glibc。
解压到 ~/.vim/tags 目录后执行 cscope 命令
1cd ~/.vim/tags/glibc-2.22 2 cscope -Rbq
在 .vimrc 中设置
1"""""""""""""""""""""""""""""""""" 2" cscope配置 3"""""""""""""""""""""""""""""""""" 4if has("cscope") 5 " 设置cscope的命令位置 6 set csprg=/usr/local/bin/cscope 7 " 设定quickfix来显示cscope的结果 8 set cscopequickfix=s-,c-,d-,i-,t-,e- 9 " 先搜索tags标签文件,在搜索cscope数据库 10 set csto=1 11 " 使用cstag查询,也就是同时搜索cscope数据库和tags标签文件 12 set cst 13 " 不显示添加数据库是否成功 14 set nocsverb 15 " 16 if filereadable("cscope.out") 17 " 添加当前目录下的cscope数据库 18 cs add cscope.out 19 else 20 " 添加vim自带的cscope数据库 21 " gnu c 数据库 22 cs add ~/.vim/tags/glibc-2.22/cscope.out ~/.vim/tags/glibc-2.22 23 endif 24 " 显示添加数据库成功 25 set csverb 26endif 27 28" 映射快捷键"<C-_>g的按法是先按"Ctrl+Shift+-", 然后很快再按"g" 29" 查找本 C 符号(可以跳过注释) 30nmap <C-_>s :cs find s <C-R>=expand("<cword>")<CR><CR> 31"查找本定义 32nmap <C-_>g :cs find g <C-R>=expand("<cword>")<CR><CR> 33"查找调用本函数的函数 34nmap <C-_>c :cs find c <C-R>=expand("<cword>")<CR><CR> 35"查找本字符串 36nmap <C-_>t :cs find t <C-R>=expand("<cword>")<CR><CR> 37"查找本 egrep 模式 38nmap <C-_>e :cs find e <C-R>=expand("<cword>")<CR><CR> 39"查找本文件 40nmap <C-_>f :cs find f <C-R>=expand("<cfile>")<CR><CR> 41"查找包含本文件的文件 42nmap <C-_>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR> 43"查找本函数调用的函数 44nmap <C-_>d :cs find d <C-R>=expand("<cword>")<CR><CR>
tagbar
tagbar 插件是和 taglist 功能类似的插件,但是它比 taglist 更优秀,并且能和 NERDTree 完美配合。
tagbar的优势
- 支持头文件的函数列表显示
细心的读者可能会发现,tagbar对函数的可见级别也是做了区分的,分别用+ – # 并配合着色来做了区分 - 对面向对象的支持更好
taglist虽然也会列出类列表,但是整体还是很不直观 - 自动根据文件修改时间来重建
taglist在这一点上体验就很不好,其实明明可以通过这种时间戳的方式来实现
- 支持头文件的函数列表显示
在vim中的安装和配置
1call vundle#begin('~/.vim/bundle/') 2" 替换taglist的插件[tagbar] 3Plugin 'majutsushi/tagbar' 4call vundle#end() 5 6"""""""""""""""""""""""""""""""""" 7" tagbar配置 8"""""""""""""""""""""""""""""""""" 9" 启动时自动focus 10let g:tagbar_autofocus=1 11" <F10>打开/关闭Tagbar 12nnoremap <silent> <F10> :TagbarToggle<CR>
rainbow
这个插件也是必备的,该插件的主要功能是给配对的(){}[]不同的颜色来区别,非常方便看括号的作用域
在 Vim 中的安装和配置
1call vundle#begin('~/.vim/bundle/') 2" 括号显示增强 3Plugin 'luochen1990/rainbow' 4call vundle#end() 5 6"""""""""""""""""""""""""""""""""" 7" rainbow配置 8"""""""""""""""""""""""""""""""""" 9" rainbow激活 10let g:rainbow_active = 1
给 rainbow 添加自动启动功能
1if (exists('g:rainbow_active') && g:rainbow_active) 2 auto syntax * call rainbow#hook() 3 auto colorscheme * call rainbow#show() 4 " 下面这命令使rainbow在vim启动时被打开 5 autocmd VimEnter * nested call rainbow#toggle() 6endif
syntastic
这是一个非常有用的插件,它能够实时的进行语法和编码风格的检查,利用它几乎可以做到编码完成后无编译错误。并且它还集成了静态检查工具:lint,可以让你的代码更加完美。更强大的它支持近百种编程语言,像是一个集大成的实时编译器。出现错误之后,可以非常方便的跳转到出错处。其样例如下图所示:
在vim中的安装和配置
1call vundle#begin('~/.vim/bundle/') 2" 语义高亮 3Plugin 'scrooloose/syntastic' 4call vundle#end() 5 6"""""""""""""""""""""""""""""""""" 7" syntastic配置 8"""""""""""""""""""""""""""""""""" 9" 首次打开和保存时都要进行语义检查 10let g:syntastic_check_on_open = 1 11" 设置错误提示符'x' 12let g:syntastic_error_symbol = 'x' 13" 设置警告提示符'!' 14let g:syntastic_warning_symbol = '!' 15" 当鼠标放在错误行则显示错误信息 16let g:syntastic_enable_balloons = 1 17" 保存退出时不用进行语义检测 18let g:syntastic_check_on_wq = 0 19" 编译有误则错误窗口显示,否在不显示 20let g:syntastic_auto_loc_list = 1 21" 错误总会填充到错误窗口 22let g:syntastic_always_populate_loc_list = 1
YouCompleteMe
YouCompleteMe 对代码的补全完全达到了编译器级别,绝不弱于 Visual Assist。它是基于 LLVM/clang,一个 Apple 公司为了代替 GNU/GCC 而支持的编译器,正因为 YouCompleteMe 有了编译器的支持,而不再像以往的插件一样基于文本来进行匹配,所以准确率才如此之高。而且,它是C/S架构,会在本机创建一个服务器端,利用 clang 来解析代码,然后将结果返回给客户端,所以也就解决了 VIM 是单线程而造成的各种补全插件速度奇慢的诟病,在使用时,几乎感觉不到任何的延时,体验达到了 Visual Assist 的级别。
YouCompleteMe 除了补全以外,还有一个非常重要的作用:代码跳转,同样可以达到编译器级别的准确度,媲美 Visual Assist 与 Source Insight 。其样例如下图所示:
安装必备软件
1sudo apt-get install clang llvm cmake python python-dev
手动编译
1cd ~/.vim/bundle/YouCompleteMe 2./install.sh --clang-completer
在vim中的安装和配置
1call vundle#begin('~/.vim/bundle/') 2" 自动补全 3Plugin 'Valloric/YouCompleteMe' 4call vundle#end() 5 6"""""""""""""""""""""""""""""""""" 7" YouCompleteMe配置 8"""""""""""""""""""""""""""""""""" 9" 设置YCM配置文件的路径 10let g:ycm_global_ycm_extra_conf='~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/ycm/.ycm_extra_conf.py' 11" 开启关键字语法检测 12let g:ycm_seed_identifiers_with_syntax = 1 13" 自动触发补全 14let g:ycm_auto_trigger = 1 15" YCM触发的条件 16let g:ycm_semantic_triggers = { 17\ 'c' : ['->' , '.'], 18\ 'cpp,objcpp' : ['->','.','::'], 19\ 'java,javascript,python,scala' : ['.'], 20\ 'ruby' : ['.','::'], 21\} 22" 不用每次询问.ycm_extra_conf.py位置 23let g:ycm_confirm_extra_conf=0 24" YCM也从tags文件中收集标识符 25let g:ycm_collect_identifiers_from_tags_files=1 26" 当输入注释的时候不用弹出提示 27let g:ycm_complete_in_comments=0 28" 当输入字符的时候弹出提示 29let g:ycm_complete_in_strings=1
TIps:Tab无效
如果出现安装 YouCompleteMe 后,虽然看到 YouCompleteMe 的提示框,但是无法使用 < Tab > 进行自动补全,只能使用上下方向键+回车来选择时,就要检查一下 .vimrc 是否打开了粘贴模式,即设置了set paste.该模式会屏蔽所有映射和缩写.(对于 ultisnips 也有同样的问题)
ultisnips
这个插件也是必备的,该插件的主要功能是用来快速输入固定的代码块,像文件开头的版权声明,#ifndef... #def... #endif
这样宏定义,markdown 写 jekyll 博文的 head 信息.最关键的是可以按照自己的习惯
自定义代码块,这样就不用按照 IDE 的习惯培养自己了.其动态效果如下所示:
在vim中的安装和配置
1call vundle#begin('~/.vim/bundle/') 2" ultisnips 3Plugin 'SirVer/ultisnips' 4" Snippets are separated from the engine 5Plugin 'honza/vim-snippets' 6call vundle#end() 7 8"""""""""""""""""""""""""""""""""" 9" ultisnips配置 10"""""""""""""""""""""""""""""""""" 11" 如果使用了Valloric/YouCompleteMe,就别设置为<tab> 12let g:UltiSnipsExpandTrigger="<c-j>" 13" 前选片段 14let g:UltiSnipsJumpForwardTrigger="<C-f>" 15" 后选片段 16let g:UltiSnipsJumpBackwardTrigger="<C-b>" 17" 使用:UltiSnipsEdit打开片段定义文件时分屏位置 18let g:UltiSnipsEditSplit="vertical"
自定义代码块
我们注意到安装 ultisnips 过程中,除了安装自身以外,还安装了 honza 的 vim-snippets,而它的一大作用是提供了大量(目前是80个)的程序片段,像 c,python,markdown,make,sh,sql 等。而这些 snippets 都在 .vim/bundle/vim-snippets/snippets 文件夹中。除此之外,我们还可以自定义自己的代码块,建议是放在 .vim/UltiSnippets 目录下(和 bundle 同等级),一方面是 .vim/bundle/vim-snippets/snippets 下的代码块是别人的 git 项目。另一方面 .vim/UltiSnippets 下的文件可以覆盖 vim-snippets 里的配置,这样更符合 DIY 的目的。关于如何编写 snippets,网上找到的资源不多,给出如下建议:查看 .vim/bundle/vim-snippets/snippets 里的代码
通过
:help snippets
查看 ultisnips 的帮助文档博文 自定义自己的代码块中的样列
1## head Jekyll写博文时插入的头文件信息 2snippet head "Jekyll post header" b # b代表begin(snippet should be expanded only at the beginning of a line ) 3--- 4layout: default 5title: ${1:blog_name} 6category: [${2:cate1,cate2}] 7comments: true 8date: `!v strftime("%Y-%m-%d %H:%M:%S")` 9--- 10${0} # 代表tab最终停留的位置 11 12endsnippet
tabular
这是一个处女座或码农必备的插件,因为当你看到代码/文字杂乱的排版–等号,冒号,表格等不能对齐时,应该会抓狂吧。而 tabular 这个插件能完美的解决这个问题。就像下面的图例一样,只需要输入命令 :Tabularize /*
(*代表对齐的符号)即可:
在 Vim 中的安装和配置
1call vundle#begin('~/.vim/bundle/') 2" tab对齐 3Plugin 'godlygeek/tabular' 4call vundle#end() 5 6"""""""""""""""""""""""""""""""""" 7" tabular配置 8"""""""""""""""""""""""""""""""""" 9" 目前还尚在摸索中
vim-markdown
vim-markdown 是一款用来对原生 markdown 和扩展 markdown 语法进行语义高亮和规则匹配的插件。
在 vim 中的安装和配置
1call vundle#begin('~/.vim/bundle/') 2" markdown语义高亮 3Plugin 'plasticboy/vim-markdown' 4call vundle#end() 5 6"""""""""""""""""""""""""""""""""" 7" tabular配置 8"""""""""""""""""""""""""""""""""" 9" vim识别md 10autocmd BufNewFile,BufReadPost *.md set filetype=markdown 11let g:vimmarkdownfoldingdisabled=1 "取消代码折叠 12let g:vimmarkdownnodefaultkeymappings=1 "取消默认的键对应 13let g:vimmarkdownmath=1 "使用数学符号 14let g:vimmarkdownfrontmatter=1 "高亮YMAL frontmatter
[markdown同步预览][markdown-preview]
markdown-preview 是一款用来将 vim 打开的 markdown 文件翻译为 html 显示在浏览器里的插件,该插件的亮点在于实时更新。
在 Vim 中的安装和配置
1call vundle#begin('~/.vim/bundle/') 2" markdown同步显示 3Plugin 'iamcco/mathjax-support-for-mkdp' 4Plugin 'iamcco/markdown-preview.vim' 5call vundle#end() 6 7"""""""""""""""""""""""""""""""""" 8" markdown-preview.vim配置 9"""""""""""""""""""""""""""""""""" 10" 设置启动chrome浏览器的命令 11let g:mkdp_path_to_chrome = "open -a Google\\ Chrome" 12" 设置为1则打开markdown文件时自动打开浏览器 13let g:mkdp_auto_start = 1 14" 设置为1则在编辑markdown的时候预览窗口是否打开,未开则自动打开 15let g:mkdp_auto_open = 1 16" 切换buffer时自动关闭预览窗口,设置为0则在切换buffer时不自动关闭 17let g:mkdp_auto_close = 1 18" 设置为1则只有在保存文件或退出插入模式时更新预览,默认为0,实时更新预览 19let g:mkdp_refresh_slow = 0 20" 设置为1则所有文件都使用MarkdownPreview进行预览,默认只有markdown文件可以 21let g:mkdp_command_for_global = 0
emmet-vim
Emmet 的前身就叫做 Zen Coding,它是个前端插件。官方支持很多软件,像 Sublime Text、Notepad++、Dreamweaver、Eclipse、Adobe Brackets 等,而 Emmet.vim 并非 Emmet 亲生,而是由日本 Yasuhiro Matsumoto 开发。对于前端开发者而言它是一件神器,能够节省大量的重复 coding 劳动。鉴于前端开发的少,这里只是 mark 一下。