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