用户名: 密码: 忘记密码? 注册

[转]vim自动补全

作者:  时间: 2010-10-19

本节所用命令的帮助入口:

:help ins-completion
:help compl-omni
:help 'omnifunc'
:help i_CTRL-X_CTRL-O
:help ins-completion-menu
:help popupmenu-keys
:help 'completeopt'
:help compl-omni-filetypes
:help omnicppcomplete.txt 

使用过Source Insight的人一定对它的自动补全功能印象深刻,在很多的集成开发环境中,也都支持自动补全。vim做为一个出色的编辑器,这样的功能当然少不了。而 且,作为一个通用的编辑器,vim实现的补全功能并不仅仅限于对程序的补全,它可以对文件名补全、根据字典进行补全、根据本缓冲区或其它缓冲区类似的内容 进行补全、根据文件语法补全等等,它甚至允许用户自己编写函数来实现定制的补全。

作为vim进阶系列文章中的一篇,本文以介绍vim对程序的补全为主,也顺带介绍一下其它的补全方式。本文将分为两篇,第一篇主要介绍vim的OMNI补全,下一篇简要介绍其它的补全方式,以及SuperTab插件。

vim的OMNI补全(以下称”全能补全”)可以支持多种程序语言,包括C,C++, XML/HTML,CSS,JAVASCRIPT,PHP,RUBY等,详细列表请参阅”:help compl-omni-filetypes“。在本文中,主要介绍C及C++的全能补全。

vim在对不同类型的文件进行补全时,会根据文件类型,为其设置不同的补全函数。也就是说,要实现全能补全功能,需要打开文件类型检测。把下面的命令加到你的vimrc中:

filetype plugin indent on 

你可以查看’omnifunc‘选项,来知道当前的补全函数是什么。

对C及C++代码的全能补全需要使用Exuberant ctags生成的标签文件,我们在前面的文章中介绍过如何使用Exuberant ctags程序来生成标签文件。不过,如果你的Exuberant ctags版本为5.5.4,那么需要为其打上增加”typename:“字段补丁,才能支持C的全能补全。补丁在这里下载:

ftp://ftp.vim.org/pub/vim/unstable/patches/ctags-5.5.4.patch

可以在这里找到MS-Windows上已经编译好的可执行版本:

http://georgevreilly.com/vim/ctags.html 

不过我建议使用最新5.6版本Exuberant Ctags。在下面的网站可以下载:

http://ctags.sourceforge.net/

你可以直接下载已经编译好的rpm版本,或者下载源代码。如果是后者,使用以下命令对源代码进行编译:

tar zvxf ctags-5.6.tar.gz
cd ctags-5.6
./configure
make
make install 

如果你没有系统目录的写权限,你可能要把Exuberant Ctags安装到自己的主目录,只需要把上面的”./configure“命令改为”./configure –prefix=/home/xxx“就可以了。

Ctags升级后,使用”ctags –R“更新一下标签文件,现在再进入vim就可以在C程序中全能补全了。我们依旧以vim 7.0的源代码为例。

例如,我们在VimMain()函数中,输入”gui“三个字符,然后按下”CTRL-X CTRL-O“,在vim的状态行会显示”Omni Completeion“,表明现在进行的是全能补全,同时会弹出一个下拉菜单,显示所有匹配的标签。你可以使用来”CTRL-P“和”CTRL-N“上下选择,在选择的同时,所选中的项就被放在光标位置,不需要再按回车来把它放在光标位置(像Source Insight那样)。

如果更习惯于使用Source Insight这种方式,你可以使用上、下光标键来选择项目,然后按回车把选中的项目放到光标位置。不过这样一来,你的手指就会离开主编辑区,并且需要多输入一个回车键。

本文结尾处提供了一个键绑定,允许在使”CTRL-P“和”CTRL-N“时,输入回车表示补全结束,而不是插入回车。

如果补全处于激活状态,可以用”CTRL-E“停止补全并回到原来录入的文字。用”CTRL-Y“可以停止补全,并接受当前所选的项目。

下图是使用”CTRL-N”选择的抓图。该图中,我选择了”gui_exit(“函数,接下来可以直接输入这个函数的参数,这会结束当前补全,并插入我所输入的参数。

下图是对结构的成员进行补全的抓图:

缺省的,vim会使用下拉菜单和一个preview窗口(预览窗口)来显示匹配项目,下拉菜单列出所有匹配的项目,预览窗口则显示选中项目的详细信息。打开预览窗口会导致下拉菜单抖动,因此我一般都去掉预览窗口的显示,这需要改变’completeopt‘的值,我的设置如下:

set completeopt=longest,menu 

上面的设置表明,只在下拉菜单中显示匹配项目,并且会自动插入所有匹配项目的相同文本。

如果要支持C++的全能补全,需要到vim主页下载OmniCppComplete插件,链接如下:

    http://www.vim.org/scripts/script.php?script_id=1520

下载后,把它解压到你的.vim目录(在windows下是vimfiles目录),它会安装以下文件:

after\ftplugin\cpp.vim
autoload\omni\common\debug.vim
\utils.vim
autoload\omni\cpp\complete.vim
\includes.vim
\items.vim
\maycomplete.vim
\namespaces.vim
\settings.vim
\tokenizer.vim
\utils.vim
doc\omnicppcomplete.txt 

确保你已关闭了vi兼容模式,并允许进行文件类型检测:

set nocp
filetype plugin on 

接下来,使用下面的命令,为C++文件生成标签文件,假定你的文件在src目录树下:

ctags -R --c++-kinds=+p --fields=+iaS --extra=+q src 

在对C++文件进行补全时,OmniCppComplete插件需要tag文件中包含C++的额外信息,因此上面的ctags命令不同于以前我们所使用的,它专门为C++语言生成一些额外的信息,上述选项的含义如下:

--c++-kinds=+p  : 为C++文件增加函数原型的标签
--fields=+iaS   : 在标签文件中加入继承信息(i)、类成员的访问控制信息(a)、以及函数的指纹(S)
--extra=+q      : 为标签增加类修饰符。注意,如果没有此选项,将不能对类成员补全 

现在,进入vim,设置好tag选项(我在前面的文章中介绍过)。好极了,vim能够对C++自动补全了!

我写了一个简单的例子,来演示C++的自动补全功能,如下图所示,在输入”t.“后,OmniCppComplete插件会自动弹出struct test1的成员供选择,而在输入”b->“后,又会自动弹出class base的成员供选择,非常方便,连”CTRL-X CTRL-O“都不必输入。OmniCppComplete插件的缺省设置比较符合我的习惯,因此不须对其设置进行调整,如果你需要调整,参阅OmniCppComplete的帮助页。

下表是我的vimrc中设置的键绑定,使用pumvisible()来判断下拉菜单是否显示,如果下拉菜单显示了,键映射为了一个值,如果未显示,又会映射为另一个值。

" mapping
inoremap <expr> <CR>       pumvisible()?"\<C-Y>":"\<CR>"
inoremap <expr> <C-J>      pumvisible()?"\<PageDown>\<C-N>\<C-P>":"\<C-X><C-O>"
inoremap <expr> <C-K>      pumvisible()?"\<PageUp>\<C-P>\<C-N>":"\<C-K>"
inoremap <expr> <C-U>      pumvisible()?"\<C-E>":"\<C-U>" 

上面的映射都是在插入模式下的映射,解释如下:

  • 如果下拉菜单弹出,回车映射为接受当前所选项目,否则,仍映射为回车;
  • 如果下拉菜单弹出,CTRL-J映射为在下拉菜单中向下翻页。否则映射为CTRL-X CTRL-O
  • 如果下拉菜单弹出,CTRL-K映射为在下拉菜单中向上翻页,否则仍映射为CTRL-K
  • 如果下拉菜单弹出,CTRL-U映射为CTRL-E,即停止补全,否则,仍映射为CTRL-U
二、

本节所用命令的帮助入口:

:help compl-generic
:help 'complete'
:help ins-completion 

上篇文章介绍了vim的智能补全(omni补全),本篇主要介绍vim提供的其它补全方式。

除智能补全外,最常用的补全方式应该是CTRL-NCTRL-P补全了。它们会在当前缓冲区、其它缓冲区,以及当前文件所包含的头文件中查找以光标前关键字开始的单词。智能补全不能对局部变量进行补全,而CTRL-NCTRL-P补全则可以很好的胜任。

下图是采用CTRL-P补全的一个例子,输出字符”pa”,然后按CTRL-P,vim会在下拉菜单中列出所有的匹配功能供选择,此时再按一下CTRL-P,就选中了第一个项目,也就是我想输入的”parmp”。我们第一次输入CTRL-P的是进行补全,第二次输入的CTRL-P是在下拉菜单中向上选择,二者的含义是不同的。

我们知道,CTRL-P一般的含义是向上,因此CTRL-P补全是向上查找以进行补全,而CTRL-N是向下查找以进行补全,在不同场合使用不同的快捷键可以加速补全的速度。

使用CTRL-NCTRL-P补全时,由’complete‘选项控制vim从哪些地方查找补全的内容。例如,对于比较大的软件项目,文件包含关系复杂,如果CTRL-NCTRL-P补全时查找所包含的头文件,耗时会比较久。此时,可以在’complete‘选项中去掉’i‘标记,这样CTRL-NCTRL-P补全就不在头文件中查找了,速度会快很多;当然,弊端就是你无法对头文件中出现的某些内容进行补全了。’complete‘选项中其它标记的含义,请阅读手册页。

vim中其它的补全方式包括:

整行补全                        CTRL-X CTRL-LCTRL-X CTRL-NCTRL-X CTRL-KCTRL-X CTRL-TCTRL-X CTRL-ICTRL-X CTRL-]CTRL-X CTRL-FCTRL-X CTRL-DCTRL-X CTRL-VCTRL-X CTRL-UCTRL-X CTRL-S 
根据当前文件里关键字补全        
根据字典补全                    
根据同义词字典补全              
根据头文件内关键字补全          
根据标签补全                    
补全文件名                      
补全宏定义                      
补全vim命令                     
用户自定义补全方式              
拼写建议                        

例如,当我们按下”CTRL-X CTRL-F“时,vim就会弹出下拉菜单,显示出当前目录下的可选目录和文件,如下图所示。这样,在输入文件名时方便多了。

灵活的运用这些补全方式,甚至自定义自己的补全方式,可以使你的工作更加高效。

可以在vimrc中定义下面的键绑定,以减少按键次数:

inoremap <C-]>             <C-X><C-]>
inoremap <C-F>             <C-X><C-F>
inoremap <C-D>             <C-X><C-D>
inoremap <C-L>             <C-X><C-L> 

SuperTab插件会记住你上次所使用的补全方式,下次再补全时,直接使用TAB,就可以重复这种类型的补全。比如,上次你使用CTRL-X CTRL-F进行了文件名补全,接下来,你就可以使用TAB来继续进行文件名补全,直到你再使用上面列出的补全命令进行了其它形式的补全。这个插件在下面的链接下载:

http://www.vim.org/scripts/script.php?script_id=1643

下载后,把它放到.vim/plugin目录就可以了。

可以对下面两个选项进行配置,以调整SuperTab的缺省行为:

  • g:SuperTabRetainCompletionType的值缺省为1,意为记住你上次的补全方式,直到使用其它的补全命令改变它;如果把它设成2,意味着记住上次的补全方式,直到按ESC退出插入模式为止;如果设为0,意味着不记录上次的补全方式。
  • g:SuperTabDefaultCompletionType的值设置缺省的补全方式,缺省为CTRL-P

你可以在vimrc中设置这两个变量,例如:

let g:SuperTabRetainCompletionType = 2
let g:SuperTabDefaultCompletionType = "<C-X><C-O>" 

现在你可以使用TAB来进行补全了,就像在shell中那样,方便了很多!



vim常用插件介绍:
 
vim是Linux下强大的编辑器之一,是每个linuxer并不可少的工具。vim的插件扩展
工能为vim增加了不少的特色。关于如何将vim打造IDE网上的资料也不少,下面只是
我自己对vim的配置。
 
推荐文章:http://blog.csdn.net/wooin 
<<手把手教你把 Vim 改装成一个 IDE 编程环境>>
 
工具或插件介绍,如想进一步了解请参照官方文档。
1) Exuberant Ctags : 它可以为你的源码产生一个tags文件,并且在tags文件中记录
源文件的索引以帮助你快速得找到某个符号的定义。它支持相当多的语言,如C、C++、C#、Shell等等。
常用命令:Ctrl+] 跳到声明定义处  Ctrl+T 跳回原处
下载地址:http://ctags.sourceforge.net

2) trinity.vim : Build the trinity of srcexpl, taglist, NERD_tree to
be a good IDE. 这个插件将 srcexpl、taglist、NERD_tree这三个插件集中起来做成IDE
taglist: Source code browser (supports C/C++, java etc)
srcexpl: A Source code Explorer based on tags works like context
         window in Source Insight
NERD_tree: A tree explorer plugin for navigating the filesystem
下载地址:http://www.vim.org/scripts/script.php?script_id=2347

3) omnicppcomplete: C/C++ omni-completion with ctags database
这个插件用于自动补全,可用于 . ->  :: 等操作符。
下载地址:http://www.vim.org/scripts/script.php?script_id=1520

4) c.vim: C/C++ IDE --  Write and run programs. Insert statements, idioms, 
comments etc. 这个插件的功能比较多,它集成了编译、链接、运行、注释等许多IDE常用的功能。
下载地址:http://www.vim.org/scripts/script.php?script_id=213

5) echofunc.vim : Echo the function declaration in the command line for C/C++.
这个插件主要用于显示函数声明。
下载地址:http://www.vim.org/scripts/script.php?script_id=1735
 
6) stl.vim: Improved C++ STL syntax highlighting.
原来的vim对C++的语法高亮不支持像string、 vector之类的STL模板类。
下载地址:http://www.vim.org/scripts/script.php?script_id=2224

7) stlrefvim.vim: A C++ Standard Template Library reference manual.
这个插件让你轻松的拥有C++ STL的文档帮助
下载地址:http://www.vim.org/scripts/script.php?script_id=2353

知道了这个插件的作用之后就可以行动了,首先需要具备一些vim的基本知识:像如何使用插件(每个插件
都有它的安装帮助)、vim一些文件夹的作用(如plugin,syntax...)、vim键映射等。
建议在使用这些插件之前先读一读它的文档,了解一下这些插件的作用和主要的功能,并且看一下它的文件
结构,大概看一下它的源码,这样就方便你以后对插件的修改(如改变快捷键映射)。这个学习过程并不困
难也无须花大量的时间。

下面是我的vim配置文件

"基本配置
set mouse=a                 "启动鼠标功能
set nocompatible         "不兼容旧版本
set nu                   "显示行号
set tabstop=4            "tab=4
set shiftwidth=4         "缩进4
set wrap                 "折行
set ruler                "在vim窗口右下角显示光标位置
set ignorecase           "忽略大小写
"set hlsearch             "查找时高亮显示
set showmode             "显示当前工作模式

syntax enable            "打开色彩
syntax on                "打开语法高亮
set cindent              "使用C语言的缩进方式
set autoindent             "自动缩进
set showmatch            "显示括号配对
set smartindent          "智能对齐
"set whichwrap+=h,l      "使用h,l移动可以跨行
"set mps+=<:>            "让<>可以使用%跳转
"set foldmarker={{{,}}}

"备份相关配置
set nobackup            
set backupext=.bak      
set writebackup          "写备份但关闭vim后自动删除
"set backupdir=path      "设置备份路径

"Omnicppcomplete Configuration
"下面两行开启了vim三种智能
"1.自动识别file类型
"2.用file type plugin脚本
"3.使用缩进定义文件
"set nocompatible
filetype plugin on
filetype indent on
let OmniCpp_DefaultNamespaces=["std"]
let OmniCpp_MayCompleteScope=1
set completeopt=longest,menu          "关掉智能补全时的预览窗口
map <silent> <F12> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR>
set tags+=/usr/include/c++/4.2.4/tags

"Tlist Configuration  taglist.vim
let Tlist_Process_File_Always=1     "Always Process File
"let Tlist_Auto_Open=1              "Open Tlist when vim start
let Tlist_Enable_Fold_Column=1       
let Tlist_Exit_OnlyWindow=1         "If only Tlist window works, vim exit.
let Tlist_Sort_Type="name"          "sort by name
let Tlist_Show_One_File=1

"echofunc Configuration
let g:EchoFuncKeyPrev='<C-b>'
let g:EchoFuncKeyNext='<C-n>'

"trinity.vim: Build the trinity of srcexpl,taglist,
"NERD_tree to be a good IDE
nmap <F8> :TrinityToggleAll<CR>
nmap <F9> :TrinityToggleSourceExplorer<CR>
nmap <F10> :TrinityToggleTagList<CR>
nmap <F11> :TrinityToggleNERDTree<CR>



还有一个函数参数补全的插件:code_complete

install details 1. Put code_complete.vim to plugin  directory.                          
2. Use the command below to create tags file including signature field.    
   ctags -R --c-kinds=+p --fields=+S .
http://www.vim.org/scripts/script.php?script_id=1764