Vim配置开发环境
tag文件
在UNIX系统下的ctags功能比较少,所以一般我们使用Exuberant Ctags(在大多数Linux 系统上,它是缺省的ctags程序),它能够支持多达33种程序语言,足以满足我们开发的 需要了。http://ctags.sourceforge.net
macs则使用etags来生成tag文件,如果希望vim也能支持etags的tag文件格式,需要编译
vim时加入+emacs_tags
选项。
tag文件格式
Tag文件需要遵循一定的格式,由Exuberant Ctags生成的tag文件,缺省是如下格式:
{tagname} {TAB} {tagfile} {TAB} {tagaddress} {term} {field} ..
-
{tagname}
– 标识符名字,例如函数名、类名、结构名、宏等。不能包含制表符。 -
{tagfile}
– 包含{tagname}
的文件。它不能包含制表符。 -
{tagaddress}
– 可以定位到{tagname}
光标位置的Ex命令。通常只包含行号或搜索 命令。出于安全的考虑,vim会限制其中某些命令的执行。 -
{term}
– 设为;"
,这是为了兼容Vi编辑器,使Vi忽略后面的{field}
字段。 -
{field} ..
– 此字段可选,通常用于表示此{tagname}的类型是函数、类、宏或其它。
在{tagname}
、{tagfile}
和{tagaddress}
之间,采用制表符\t
分隔,也就是说
{tagname}
、{tagfile}
的内容中不能包含制表符。
Tag文件的开头可以包含以!_TAG_
开头的行,用来在tag文件中加入其它信息。vim能够
识别两种这样的标记,经常用到的是_TAG_FILE_SORTED
标记,例如:
!_TAG_FILE_SORTED<Tab>1<Tab>{anything}
上面这个标记说明tag文件是经过排序的,并且排序时区分了大小写,对排序的tag,vim会 使用二分法来进行查找,大大加快了查找速度:
-
如果值为
0
,则表示tag文件未经排序; -
如果值为
1
,则表示tag文件区分大小写排序; -
如果值为
2
,则表示tag文件是忽略大小写排序的。
之所以在这里介绍tag文件的格式,是因为我们在后面提到的lookupfile插件中,会自己 生成tag文件。
生成tag
虽然ctags有为数众多的选项,但通常我们所使用的非常简单。还是以vim 7.0的代码为例 ,我们执行:
cd ~/src/vim70 ctags –R src
上面这条命令会在~/src/vim70/
目录下生成一个名为tags的文件,这个文件中包含
~/src/vim70/src/
目录下所有.c
、.h
文件中的标签。它一个文本文件,你可以用
vim打开它看一下。此文件缺省按区分字母大小写排序,所以直接可以被vim使用。
vim中使用tag
现在我们进入vim,执行下面的命令:
:cd ~/src/vim70 "切换当前目录为~/src/vim70 :set tags=tags "设置tags选项为当前目录下的tags文件
现在,我们设置好了tags选项,接下来我们使用它:
:tag VimMain
你会看到vim打开了src/main.c
文件,并把光标定位到第167行VimMain上。
我们知道,一般主程序的函数名为main,如果你尝试下面的命令:
:tag main # pri kind tag file 1 F f main src/xxd/xxd.c main(argc, argv) 2 FS d main src/if_python.c 46 Choice number (<Enter> cancels):
这里并没有src/main.c
文件,怎么回事呢?这是因为ctags并不是编译器,它在处理
编译预处理指令受到局限,因此并没有生成src/main.c
中main()
函数的标签。你可以
在生成tag文件时给ctags指定参数来解决这个问题。见ctags手册。
或者你可以用:grep
或:vimgrep
来查找main(参见grep及vimgrep的部分):
:cd ~/src/vim70 :vimgrep /\<main\>/ src/*.c :cw
这时下面的quickfix窗口将显示出来,在quickfix窗口中找到我们想跳转的位置(本例中是
src/main.c
),按回车,就可以跳到对应的位置了。
如果你只记得部分的标签名,那么可以使用tag
命令的搜索模式,你可以输入一个
vim正则表达式来表示你所查找的名字,如:
:tag /\C\<\k\+ain\> # pri kind tag file 1 F f VimMain src/main.c VimMain 2 F d bindtextdomain src/vim.h 483 3 F d bindtextdomain src/vim.h 502 4 F d bindtextdomain src/vim.h 504 5 F f main src/xxd/xxd.c main(argc, argv) 6 F d textdomain src/vim.h 488 7 F d textdomain src/vim.h 510 8 F d textdomain src/vim.h 512 9 FS d bindtextdomain src/gui_gtk.c 54 10 FS d bindtextdomain src/gui_gtk_x11.c 37 11 FS f cmdsrv_main src/main.c cmdsrv_main(argc, argv, serverName_arg, serverStr) 12 FS d main src/if_python.c 46 13 FS d textdomain src/gui_gtk.c 51 14 FS d textdomain src/gui_gtk_x11.c 34 Choice number (<Enter> cancels):
这表示我想查找一个以一个或多个keyword开始的标签,此标签以ain
做为结尾,在
查找时区分大小写。要读懂这个正则表达式,请:help pattern
。
vim会保存一个跳转的标签栈,以允许你在跳转到一个标签后,再跳回来,可以使用
:tags
命令查找你处于标签栈的哪个位置。
我们经常用到的tag跳转命令见下(一般只需要知道CTRL-]和CTRL-T就可以了):
-
:tag {ident}
:"跳转到指定的标签 -
:tags
:"显示标签栈 -
CTRL-]
:"跳转到当前光标下的标签 -
CTRL-T
:"跳到标签栈中较早的标签
如果想了解更多命令,可以:help 29.1
(强烈建议程序员完整的阅读usr_29.txt
和
usr_30.txt
)。
如果想更深入了解tag命令和相关知识,可以:help tagsrch
。
cscope
本节所用命令的帮助入口:
:help cscope
在前面的文章中介绍了利用tag文件,跳转到标签定义的地方。但如果想查找函数在哪里 被调用,或者标签在哪些地方出现过,ctags就无能为力了,这时需要使用更为强大的 cscope。
Cscope具有纯正的Unix血统,它最早是由贝尔实验室为PDP-11计算机开发的,后来成为 商用的AT&T Unix发行版的组成部分。直到2000年4月,这个工具才由SCO公司以BSD license开源发行。
Cscope的主页在http://cscope.sourceforge.net/
在windows上也可以使用cscope,在cscope的主页上可以下载到由DJGPP编译器编译的 cscope for windows,不过这个版本不能和vi一起工作。或者你可以下载cygwin工具包( http://www.cygwin.com/),这个工具包中也包含了cscope。
在http://iamphet.nm.ru/cscope/有Sergey Khorev预编译的一个Win32版本的cscope ,这个版本的cscope可以很好的与windows版本的vim搭配使用。
生成cscope数据库
cscope的用法很简单,首先需要为你的代码生成一个cscope数据库。在你的项目根目录 运行下面的命令:
cscope -Rbq
这些选项的含义见后面。这个命令会生成三个文件:cscope.out
,cscope.in.out
,
cscope.po.out
。
其中cscope.out是基本的符号索引,后两个文件是使用-q
选项生成的,可以加快cscope的
索引速度。
在缺省情况下,cscope在生成数据库后就会进入它自己的查询界面,我们一般不用这个
界面,所以使用了-b
选项。如果你已经进入了这个界面,按CTRL-D
退出。
Cscope在生成数据库中,在你的项目目录中未找到的头文件,会自动到/usr/include
目录中查找。如果你想阻止它这样做,使用-k
选项。
添加解析的类型
Cscope缺省只解析C文件(.c和.h)、lex文件(.l)和yacc文件(.y),虽然它也可以支持C++ 以及Java,但它在扫描目录时会跳过C++及Java后缀的文件。如果你希望cscope解析C++或 Java文件,需要把这些文件的名字和路径保存在一个名为cscope.files的文件。当cscope 发现在当前目录中存在cscope.files时,就会为cscope.files中列出的所有文件生成索引 数据库。通常我们使用find来生成cscope.files文件,仍以vim 7.0的源代码为例:
cd ~/src/vim70 find . -type f > cscope.files cscope -bq
这条命令把~src/vim70
目录下的所有普通文件都加入了cscope.files
,这样,
cscope会解析该目录下的每一个文件。上面的cscope命令并没有使用-R
参数递归查找
子目录,因为在cscope.files中已经包含了子目录中的文件。
也可以手动指定要找的文件类型而不是目录下的所有文件类型:
find . -name "*.h" -o -name "*.c"-o -name "*.cc" > cscope.files
注意:find命令输出的文件以相对路径表示,所以cscope.out的索引也相对于当前路径。
如果你要在其它路径中使用当前的cscope.out,需要使用下面介绍的-P
选项。
Cscope只在第一次解析时扫描全部文件,以后再调用cscope,它只扫描那些改动过的文件 ,这大大提高了cscope生成索引的速度。
下表中列出了cscope的常用选项:
-
-R
: 在生成索引文件时,搜索子目录树中的代码 -
-b
: 只生成索引文件,不进入cscope的界面 -
-q
: 生成cscope.in.out和cscope.po.out文件,加快cscope的索引速度 -
-k
: 在生成索引文件时,不搜索/usr/include目录 -
-i
: 如果保存文件列表的文件名不是cscope.files时,需要加此选项告诉cscope到 哪儿去找源文件列表。可以使用-
,表示由标准输入获得文件列表。 -
-Idir
: 在-I选项指出的目录中查找头文件 -
-u
: 扫描所有文件,重新生成交叉索引文件 -
-C
: 在搜索时忽略大小写 -
-Ppath
: 在以相对路径表示的文件前加上的path,这样,你不用切换到你数据库文件 所在的目录也可以使用它了。
vim中使用cscope
要在vim中使用cscope的功能,需要在编译vim时选择+cscope
。vim的cscope接口先会
调用cscope的命令行接口,然后分析其输出结果找到匹配处显示给用户。
在vim中使用cscope非常简单,首先调用cscope add
命令添加一个cscope数据库,然后
就可以调用cscope find
命令进行查找了。vim支持8种cscope的查询功能,如下:
-
s
: 查找C语言符号,即查找函数名、宏、枚举值等出现的地方 -
g
: 查找函数、宏、枚举等定义的位置,类似ctags所提供的功能 -
d
: 查找本函数调用的函数 -
c
: 查找调用本函数的函数 -
t
: 查找指定的字符串 -
e
: 查找egrep模式,相当于egrep功能,但查找速度快多了 -
f
: 查找并打开文件,类似vim的find功能 -
i
: 查找包含本文件的文件
例如,我们想在vim 7.0的源代码中查找调用do_cscope()
函数的函数,我们可以输入:
:cs find c do_cscope
,回车后发现没有找到匹配的功能,可能并没有函数调用
do_cscope()
。我们再输入:cs find s do_cscope
,查找这个C符号出现的位置,现在
vim列出了这个符号出现的所有位置。
我们还可以进行字符串查找,它会双引号或单引号括起来的内容中查找。还可以输入一个 正则表达式,这类似于egrep程序的功能,但它是在交叉索引数据库中查找,速度要快得多 。
vim提供了一些选项可以调整它的cscope功能:
-
cscopecscopeprg
选项用于设置cscope程序的位置。 -
cscopecscopequickfix
设定是否使用quickfix窗口来显示cscope的结果,详情请:help cscopequickfix
; -
如果你想vim同时搜索tag文件以及cscope数据库,设置
cscopecscopetag
选项; -
cscopecscopetagorder
选项决定是先查找tag文件还是先查找cscope
数据库。 设置为0
则先查找cscope数据库,设置为1先查找tag文件。我通常设置为1
,因为在 tag文件中查找到的结果,会把最佳匹配列在第一位。
vim的手册中给出了使用cscope的建议方法,使用命令:help cscope-suggestions
查看。
下面是我的vimrc中关于cscope接口的设置:
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " cscope setting """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" if has("cscope") set csprg=/usr/bin/cscope set csto=1 set cst set nocsverb " add any database in current directory if filereadable("cscope.out") cs add cscope.out endif set csverb endif 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> 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>
下面的两个链接是cscope主页提供的cscope使用方法,也可以作为参考:
vim/cscope指导:http://cscope.sourceforge.net/cscope_vim_tutorial.html
在大项目中使用cscope:http://cscope.sourceforge.net/large_projects.html
在vim的网站上有很多与cscope相关的插件,有兴趣可以去看一下。
windows下cscope的错误
在windows上使用cscope时,你可能会遇到-q
选项被忽略的提示,解决办法:
在cygwin的shell界面中使用cscope,没有出现上面的错误提示。但如果打开windows的 命令行窗口cmd.exe,在里面执行cscope,则会出现上面的错误。
在cygwin的shell窗口中,PATH环境变量的设置会使其先找到GNU版的sort.exe, 所以上述cscope命令执行可以成功。但在cmd.exe窗口中,PATH环境变量会使其先找到 windows自带的sort.exe而不是GNU sort.exe,所以会出现上面的错误提示。
知道了问题的原因,解决方法就很简单了,我们可以写一个批处理程序,在此程序中重设
PATH
环境变量,使cscope使用GNU版的sort.exe。示例程序如下:
D:\Temp> type cs.bat @echo off set path=c:\cygwin\bin; cscope -Rbkq
在这个批处理里,首先把path环境变量指向c:\cygwin\bin
;,我的cscope.exe和GNU版的
sort.exe都在此目录中。接下来现执行cscope命令,现在它使用的就是GNU版的sort.exe了
。
目前只能在unix系列操作系统下使用cscope,虽然也有windows版本的cscope,不过还有 很多bug。在Linux技术中坚站上看到有作者在win2000上成功运行了gvim + cscope,详情 可以参阅: http://www.chinalinuxpub.com/bbs/showthread.php?t=30185
(2009/04/06更新)网友mslk提供了cscope 15.7的win32编译版本下载,下载地址: http://sourceforge.net/project/showfiles.php?group_id=196604&package_id=232374
感谢他的辛勤工作,大家有时间去他的MSLK项目看看,这个项目目的是为Linux下的工具 提供预编译的windows版本。
在vim的网站上,也有人在cygwin中成功运行了vim + cscope,详情请参阅: http://vim.sourceforge.net/tips/tip.php?tip_id=338
另外,还有人在windows上安装了XFree86包,然后在Xwindow中运行gvim + cscope。 这同样可以在上面的网页中看到。
cscope的主页在:http://cscope.sourceforge.net/
taglist
当前文件中的宏、全局变量、函数等tag显示在Symbol窗口,用鼠标点上述tag,就跳到该 tag定义的位置;可以按字母序、该tag所属的类或scope,以及该tag在文件中出现的位置 进行排序;如果切换到另外一个文件,Symbol窗口更新显示这个文件中的tag。
要使用taglist plugin,必须满足:
- 打开vim的文件类型自动检测功能:filetype on
- 系统中装了Exuberant ctags工具,并且taglist plugin能够找到此工具(因为taglist 需要调用它来生成tag文件)
- 你的vim支持system()调用
现在我们到http://www.vim.org/scripts/script.php?script_id=273下载最新版本的taglist plugin,目前版本是4.3。
下载后,把该文件在~/.vim/
目录中解压缩,这会在你的~/.vim/plugin
和~/.vim/doc
目录中各放入一个文件:
plugin/taglist.vim – taglist插件 doc/taglist.txt - taglist帮助文件
注:windows用户需要把这个插件解压在你的$vim/vimfiles
或
$HOME/vimfiles
目录。
使用下面的命令生成帮助标签(下面的操作在vim中进行):
:helptags ~/.vim/doc
生成帮助标签后,你就可以用下面的命令查看taglist的帮助了:
:help taglist.txt
Taglist提供了相当多的功能,我的vimrc中这样配置:
"""""""""""""""""""""""""""""" " Tag list (ctags) """""""""""""""""""""""""""""" if MySys() == "windows" "设定windows系统中ctags程序的位置 let Tlist_Ctags_Cmd = 'ctags' elseif MySys() == "linux" "设定linux系统中ctags程序的位置 let Tlist_Ctags_Cmd = '/usr/bin/ctags' endif let Tlist_Show_One_File = 1 "不同时显示多个文件的tag,只显示当前文件的 let Tlist_Exit_OnlyWindow = 1 "如果taglist窗口是最后一个窗口,则退出vim let Tlist_Use_Right_Window = 1 "在右侧窗口中显示taglist窗口
这样配置后,当你输入:TlistOpen
时,显示taglist窗口:
在屏幕右侧出现的就是taglist窗口,你从中可以看到在main.c文件中定义的所有tag: 宏、定义、变量、函数等;你也可以双击某个tag,跳到该tag定义的位置;你还可以把 某一类的tag折叠起来(使用了vim的折行功能),方便查看,就像上图中macro和variable 那样。更多的功能,请查看taglist的帮助页,本文也会介绍一些常用功能。
下面介绍常用的taglist配置选项,你可以根据自己的习惯进行配置:
-
Tlist_Ctags_Cmd
选项用于指定你的Exuberant ctags程序的位置,如果它没在你PATH 变量所定义的路径中,需要使用此选项设置一下; -
如果你不想同时显示多个文件中的tag,设置
Tlist_Show_One_File
为1。缺省为显示 多个文件中的tag; -
设置
Tlist_Sort_Type
为name可以使taglist以tag名字进行排序,缺省是按tag在 文件中出现的顺序进行排序。按tag出现的范围(即所属的namespace或class)排序, 已经加入taglist的TODO List,但尚未支持; -
如果你在想taglist窗口是最后一个窗口时退出vim,设置
Tlist_Exit_OnlyWindow
为1; -
如果你想taglist窗口出现在右侧,设置
Tlist_Use_Right_Window
为1
。缺省显示在 左侧。 -
在gvim中,如果你想显示taglist菜单,设置
Tlist_Show_Menu
为1
。你可以使用Tlist_Max_Submenu_Items
和Tlist_Max_Tag_Length
来控制菜单条目数和所显示 tag名字的长度; -
缺省情况下,在双击一个tag时,才会跳到该tag定义的位置,如果你想单击tag就跳转,
设置
Tlist_Use_SingleClick
为1
; -
如果你想在启动vim后,自动打开taglist窗口,设置
Tlist_Auto_Open
为1; -
如果你希望在选择了tag后自动关闭taglist窗口,设置
Tlist_Close_On_Select
为1
; -
当同时显示多个文件中的tag时,设置
Tlist_File_Fold_Auto_Close
为1
,可使 taglist只显示当前文件tag,其它文件的tag都被折叠起来。 -
在使用
:TlistToggle
打开taglist窗口时,如果希望输入焦点在taglist窗口中,设置Tlist_GainFocus_On_ToggleOpen
为1
; -
如果希望taglist始终解析文件中的tag,不管taglist窗口有没有打开,设置
Tlist_Process_File_Always
为1
; -
Tlist_WinHeight
和Tlist_WinWidth
可以设置taglist
窗口的高度和宽度。Tlist_Use_Horiz_Window
为1
设置taglist窗口横向显示;
在taglist窗口中,可以使用下面的快捷键:
-
<CR>
:跳到光标下tag所定义的位置,用鼠标双击此tag功能也一样 -
o
:在一个新打开的窗口中显示光标下tag -
<Space>
:显示光标下tag的原型定义 -
u
:更新taglist窗口中的tag -
s
:更改排序方式,在按名字排序和按出现顺序排序间切换 -
x
:taglist窗口放大和缩小,方便查看较长的tag -
+
:打开一个折叠,同zo -
-
:将tag折叠起来,同zc -
*
:打开所有的折叠,同zR -
=
:将所有tag折叠起来,同zM -
[[
:跳到前一个文件 -
]]
:跳到后一个文件 -
q
:关闭taglist窗口 -
<F1>
:显示帮助
-
用
:TlistOpen
打开taglist窗口, -
用
:TlistClose
关闭taglist窗口。 -
用
:TlistToggle
在打开和关闭间切换。
在我的vimrc中定义了下面的映射,使用<F9>
键就可以打开/关闭taglist窗口:
map <silent> <F9> :TlistToggle<cr>
Taglist插件还提供了很多命令,你甚至可以用这些命令创建一个taglist的会话,然后在下次进入vim时加载此会话。
[Taglist插件还可以与winmanager插件协同使用: [http://easwy.com/blog/archives/advanced-vim-skills-netrw-bufexplorer-winmanager-plugin/]]
lookupfile
Lookupfile插件可以在下面的链接下载: http://www.vim.org/scripts/script.php?script_id=1581
它使用vim 7.0中插入模式下的下拉菜单补全功能,因此只能在vim 7.0及以上版本中使用。
下载该插件后,把它解压到你的~/.vim目录中,就完成了安装。然后在vim中执行
:helptags ~/.vim/doc
命令,生成help文件索引,然后就可以使用:help lookupfile
命令查看lookupfile插件的帮助文件了。
注:windows用户需要把这个插件解压在你的$vim/vimfiles
或
$HOME/vimfiles
目录。
Lookupfile插件还需要最新的genutils支持,因此,需要下载genutils: http://www.vim.org/scripts/script.php?script_id=197
这个插件提供了一些通用的函数,可供其它的脚本使用。它的安装方法也是在~/.vim
目录
解压就可以了。需要注意的是,最新版本的genutils使用了新的自动加载方式,所以和
以前的版本不兼容。如果你的其它插件需要使用genutils的旧版本的话,你需要参照
genutils的说明进行配置,以便使新旧两个版本能协同工作。
现在我们介绍lookupfile插件。虽然名字为lookupfile,其实这个插件它不仅能用来查找 文件,还可以在打开的缓冲区中查找,按目录查找,等等。
项目文件查找
Lookupfile在查找文件时,需要使用tag文件。它可以使用ctags命令生成的tag文件,不过 查找效率会比较低。因此我们会专门为它生成一个包含项目中所有文件名的tag文件。
我编写了下面的shell脚本,为vim70的源代码,生成一个文件名tag文件。
#!/bin/sh # generate tag file for lookupfile plugin echo -e "!_TAG_FILE_SORTED\t2\t/2=foldcase/" > filenametags find . -not -regex '.*\.\(png\|gif\)' -type f -printf "%f\t%p\t1\n" | \ sort -f >> filenametags
回想一下我们在使用标签(tag)文件一文中介绍的tag文件的格式。再对照脚本命令来看:
-
echo命令用来生成filenametags文件中的
!_TAG_FILE_SORTED
行,表明此tag文件是 经过排序的。 -
find命令用来查找所有类型为普通文件,文件后缀名不是.png和.gif的文件,找到的
文件按
文件名\t文件路径\t1
的格式输出出来。 - sort命令则把find命令的输出重新排序,然后写入filenametags文件中
在~/src/vim70/
目录下运行该脚本,会生成一个名为filenametags的文件,包含了vim70
目录下的所有文件的名字及其所在目录。
现在我们需要让lookupfile插件知道到哪去找文件名tag文件。我们假定vim当前工作目录
为~/src/vim70/
,执行下面的命令:
:let g:LookupFile_TagExpr = '"./filenametags"'
注:如果不设定g:LookupFile_TagExpr
的值,那么lookupfile插件会以tags选项定义的
文件作为它的tag文件。
现在我们就可以使用lookupfile来打开文件了,按<F5>
或输入:LookupFile
在当前
窗口上方打开一个lookupfile小窗口,开始输入文件名(至少4个字符),随着你的输入,
符合条件的文件就列在下拉列表中了。文件名可以使用vim的正则表达式,这大大方便了
文件的查找。你可以用CTRL-N
和CTRL-P
(或者用上、下光标键)来在下拉列表中选择
你所需的文件。选中文件后,按回车,就可以在之前的窗口中打开此文件。
下图是使用lookupfile插件查找文件的一个例子:
在屏幕最上方的窗口就是lookupfile窗口,在这个窗口中输入gui.*x11
几个字符,
查找到6个匹配文件,使用CTRL-N
选中gui_x11.c
文件,然后按回车,就会在前一个
vim窗口中打开src/gui_x11.c
文件,lookupfile窗口也自动关闭了。是不是非常方便
?!
缓冲区查找
在开发过程中,我经常会同时打开数十甚至上百个文件。即使是使用BufExplorer插件, 想在这么多buffer中切换到自己所要的文件,也不是件容易的事。
Lookupfile插件提供了一个按缓冲区名字查找缓冲区的方式,只要输入缓冲区的名字 (可以是正则表达式),它就可以把匹配的缓冲区列在下拉列表中,同时还会列出该 缓冲区内文件的路径,当你的buffer中有多个同名文件时,这可以帮你迅速找到你想要的文件。
使用:LUBufs
命令开始在缓冲区中查找,输入缓冲区的名字,在你输入的过程中,符合
条件的缓冲区就显示在下拉列表中了,选中所需缓冲区后,按回车,就会切换你所选的
缓冲区。
浏览目录
Lookupfile插件还提供了目录浏览的功能,使用:LUWalk
打开lookupfile窗口后,就可以
输入目录,lookupfile会在下拉列表中列出这个目录中的所有子目录及文件供选择,如果
选择了目录,就会显示这个目录下的子目录和文件;如果选择了文件,就在vim中打开这个
文件。
Lookupfile配置
Lookupfile插件提供了一些配置选项,通过调整这些配置选项,使它更符合你的工作习惯 。下面是我的vimrc中关于lookupfile的设置,供参考:
"""""""""""""""""""""""""""""" " lookupfile setting """""""""""""""""""""""""""""" let g:LookupFile_MinPatLength = 2 "最少输入2个字符才开始查找 let g:LookupFile_PreserveLastPattern = 0 "不保存上次查找的字符串 let g:LookupFile_PreservePatternHistory = 1 "保存查找历史 let g:LookupFile_AlwaysAcceptFirst = 1 "回车打开第一个匹配项目 let g:LookupFile_AllowNewFiles = 0 "不允许创建不存在的文件 if filereadable("./filenametags") "设置tag文件的名字 let g:LookupFile_TagExpr = '"./filenametags"' endif "映射LookupFile为,lk nmap <silent> <leader>lk :LUTags<cr> "映射LUBufs为,ll nmap <silent> <leader>ll :LUBufs<cr> "映射LUWalk为,lw nmap <silent> <leader>lw :LUWalk<cr>
有了上面的定义,当我输入,lk
时,就会在tag文件中查找指定的文件名;当输入,ll
时
,就会在当前已打开的buffer中查找指定名字的buffer;当输入,lw
时,就会在指定
目录结构中查找。
另外,我还在项目相关的配置文件vim70sx.vim
(参考保存项目相关配置)中加入了
lookupfile所使用的tag文件的信息:
" lookup file tag file let g:LookupFile_TagExpr = '"filenametags"'
这样,在恢复前次会话时就给lookupfile插件定义了tag文件。
在用lookupfile插件查找文件时,是区分文件名的大小写的,如果想进行忽略大小写的
匹配,可以使用vim忽略大小写的正则表达式,即在文件名的前面加上\c
字符。举个例子
,当你输入\cab.c
时,你可能会得到ab.c
、Ab.c
、AB.c
…
注:如果想加快lookupfile忽略大小写查找的速度,在生成文件名tag文件时,使用混合 大小写排序。这在文章使用标签(tag)文件有所提及。
通常情况下我都进行忽略大小写的查找,每次都输入\c
很麻烦。没关系,lookupfile
插件提供了扩展功能,把下面这段代码加入你的vimrc中,就可以每次在查找文件时都忽略
大小写查找了:
" lookup file with ignore case function! LookupFile_IgnoreCaseFunc(pattern) let _tags = &tags try let &tags = eval(g:LookupFile_TagExpr) let newpattern = '\c' . a:pattern let tags = taglist(newpattern) catch echohl ErrorMsg | echo "Exception: " . v:exception | echohl NONE return "" finally let &tags = _tags endtry " Show the matches for what is typed so far. let files = map(tags, 'v:val["filename"]') return files endfunction let g:LookupFile_LookupFunc = 'LookupFile_IgnoreCaseFunc'
有时在LUBufs时也需要忽略缓冲区名字的大小写,我是通过直接修改lookupfile插件的
方法,在LUBufs查找的字符串前都加上\c
,使之忽略大小写。如果你不想这样,可以
每次在缓冲区名字前手动加上\c
。
本文关于Lookupfile插件就介绍这么多,请阅读手册获取更多的信息。
文件类型检测
本节所用命令的帮助入口:
:help filetype :help setfiletype :help modeline :help 'modelines' :help 'shiftwidth' :help 'expandtab' :help autocmd
打开文件类型检测功能很简单,在你的vimrc中加入下面一句话就可以了:
filetype plugin indent on
如果你用的是vim自带的示例vimrc,那么你已经打开了文件类型检测功能。或者,
也可以输入:filetype
命令查看你的文件类型检测功能有没有打开。
这条命令究竟做了什么呢?我们在下面详细介绍。
其实,上面这一条命令,可以分为三条命令:
filetype on filetype plugin on filetype indent on
我们逐条介绍这三条命令。
filetype on
filetype on
命令打开文件类型检测功能,它相当于文件类型检测功能的开关。执行时,
vim实际上执行的是$vimRUNTIME/filetype.vim
脚本。这个脚本使用了自动命令
(autocmd)来根据文件名来判断文件的类型,如果无法根据文件名来判断出文件类型,
它又会调用$vimRUNTIME/scripts.vim
来根据文件的内容设置文件类型。有兴趣可以
读一下这两个脚本,以获得更深的认识。
在上述步骤完成后,绝大多数已知类型的文件,都能被正确检测出文件类型。如果文件的
类型未能被正确的检测出来,就需要手工设置文件类型,这可以通过set filetype
完成
,例如,如果你把main.c
改名为main.c.bak1
,那么它就无法被正确检测出文件类型。
通过下面的Ex命令,就可以把它的文件类型设为c:
:set filetype=c
或者,你可以在文件中加入一个模式行,来指明这个文件的类型。vim在打开文件时,
会在文件首、尾的若干行(行数由modelines
选项决定,缺省为5行)检测具有vim特殊
标记的行,称为模式行。如果检测到,就使用模式行中定义的选项值,来修改该缓冲区的
选项。你可以留意一下vim的帮助页,每个文件的最后一行都是这样的模式行。
针对上例,我们可以在main.c.bak1的第一行或最后一行加上下面的内容,要指定这个文件 的类型:
/* vim: ft=c */
ft
是filetype
的缩写,vim中很多命令、选项都有缩写形式,以方便使用。
注意/*
与vim:
间的空格。在*/
与」ft=c「间,也需要有至少一个空格,这是模式行
格式的要求,更多信息参阅:help modeline
。
检测出文件的类型有什么作用呢?我们知道,不同类型的文件具有不同的格式,vim通过 对文件类型的识别,可以为不同类型的文件,设置不同的选项值、定义不同键绑定等。 例如,对于c类型的文件,它就和bash脚本有不同的注释格式、不同的缩进格式、不同的 关键字等。vim在设置文件类型后,会触发FileType事件,执行FileType相关的自动命令, 对不同类型的文件区别对待。
filetype plugin on
上面提到的filetype plugin on
,允许vim加载文件类型插件。当这个选项打开时,
vim会根据检测到的文件类型,在runtimepath
中搜索该类型的所有插件,并执行它们。
实际上是执行$vimRUNTIME/ftplugin.vim
脚本,有兴趣可以读一下这个脚本。这
个脚本中会设置自动命令,在runtimepath中搜索文件类型插件。
runtimepath的定义在不同的系统上不一样,对UNIX系统来说,这些路径包括:
\(HOME/.vim
、\)vim/vimfiles
、\(vimRUNTIME
、\)vim/vimfiles/after
、
$HOME/.vim/after
。
它会在上述这几个目录的ftplugin子目录中搜索所有名为c.vim
、c_*.vim
,和
c/*.vim
的脚本,并执行它们。在搜索时,它按目录在runtimepath中出现的顺序进行
搜索。缺省的,它会执行$vimRUNTIME/ftplugin/c.vim
,在这个脚本里,会设置c语言
的注释格式、智能补全函数等等。
filetype indent on
允许vim为不同类型的文件定义不同的缩进格式。这条命令也是通过一个脚本来完成加载:
$vimRUNTIME/indent.vim
。和filetype plugin on
类似,它也通过设置自动命令,
在runtimepath的indent子目录中搜索缩进设置。对c类型的文件来说,它只是打开了
cindent
选项。
我们了解了文件类型检测的用途及它是如何工作的之后,就可以根据自己的需要,来对 特定的文件类型进行特殊设置。
例如,我们在上篇文章中介绍过lookupfile插件,在它打开一个缓冲区时,会把缓冲区的 filetype设置为lookupfile,我们可以利用这一点,在这个缓冲区里进行一些特殊的配置 。例如,我们创建一个名为lookupfile.vim的文件,其内容为:
" close lookupfile window by two <Esc> nnoremap <buffer> <Esc><Esc> <C-W>q inoremap <buffer> <Esc><Esc> <Esc><C-W>q
它定义了两个局部于缓冲区的键绑定,无论在normal模式还是插入模式,只要连按两次
ESC
,就关闭当前缓冲区。
把这个文件保存到你的runtimepath所指向任一目录的ftplugin子目录中
(一般是放在~/.vim/ftplugin
目录中)。你在下次打开lookupfile窗口时,
试试连按两次ESC,是不是lookupfile窗口就关闭了?这样设置,非常适合vim中
按ESC取消命令的习惯,效率也高。
如果你对vim缺省文件类型插件的设置不太满意,那么可以把这个全局插件拷贝到
$HOME/.vim/plugin
目录中,然后更改其中的设置。你可以留意一下vim缺省的
文件类型插件,它们的头部都有这样的代码:
" Only do this when not done yet for this buffer if exists("b:did_ftplugin") finish endif
这类似于C语言头文件中的#ifndef XXX | #define XXX
的语句,可以防止该插件
被执行多次。因此,把这个插件拷贝到$HOME/.vim/plugin
中(这个目录在runtimepath
中排在最前面),它将先于vim的缺省插件被加载;而它加载后,vim的缺省文件类型插件
就不会再被加载了。这就达到了我们修改设置的目的。
不过我们通常不用这种方法。如果这样做,一旦vim的缺省插件做了改变,我们也要更新
我们改过的插件才行。我们可以在载入全局插件以后否决一些设置。在Unix 上,我们可以
把我们的设置放在~/.vim/after/ftplugin/
目录中,这个目录中的脚本会在vim的缺省
脚本后执行。这样就可以修改配置,或增加我们自己的定义。
举个例子,在多人一起开发项目时,为了使代码风格尽量保持一致,一般不允许在代码中 使用TAB符,而以4个空格代之。我们可以编辑一个文件,包含下面的内容:
set shiftwidth=4 set expandtab
把这个文件保存为~/.vim/after/ftplugin/c.vim
。这样:
- 每次在编辑c文件时,自动缩进为4个空格;
-
当你在插入模式下使用
CTRL-D
、CTRL-T
缩进时,它也会调整4个空格的缩进; - 当你按TAB键时,它将会插入8个空格……
如果你想上面的设置对h文件也生效的话,需要把它另存一份:
~/.vim/after/ftplugin/cpp.vim
,因为h文件的文件类型被设为cpp。
我们知道,vim在设置文件类型时,会触发FileType自动命令,因此,上面的例子可以用 下面的自动命令来实现:
autocmd FileType c,cpp set shiftwidth=4 | set expandtab
把这个命令放在你的vimrc中,可以起到和上例同样的效果。
vim的语法高亮功能,也要用到文件类型,来对不同的关键字进行染色。这我们将在下一篇文章中介绍。
语法高亮
本节所用命令的帮助入口:
:help syn-enable :help :colorscheme :help :highlight :help highlight-groups :help 2html.vim
启用高亮
首先,把下面的Ex命令加入你的vimrc,打开vim的语法高亮功能:
syntax enable
这条命令,实际上是执行$vimRUNTIME/syntax/syntax.vim
脚本。如果你还没有打开
文件类型检测功能,在这个脚本里会把它打开,因为要语法高亮,首先需要知道是什么
文件类型。然后它会安装Filetype自动命令,在检测到文件类型时,设置syntax选项。
而对syntax选项进行设置,又会触发Syntax自动命令,这条自动命令会在runtimepath的
syntax子目录搜寻该类型的语法文件,并使用缺省的配色方案进行染色。
配色
因此我在vimrc中加入这样一句话:
colorscheme darkblue
有一个名为Color Scheme Explorer的插件,可以帮助你快速浏览你所安装的color scheme ,在这里下载:
http://www.vim.org/scripts/script.php?script_id=1298
选择了喜欢的colorscheme后,在vimrc中加入一条colorscheme
命令,以后vim就会使用
你选定的配色方案了。
如果对配色方案某些颜色不太满意,那么你可以在原来配色方案的基础上,修改其中的
一些定义。例如,我把desert.vim拷到.vim/color
目录,重命名为darkblue_my.vim
。然后做如下更改(只列出改变的内容):
let colors_name = "darkblue_my" hi Normal guifg=#c0c0c0 guibg=#294d4a ctermfg=gray ctermbg=black ...... "Omni menu colors hi Pmenu guibg=#444444 hi PmenuSel ctermfg=7 ctermbg=4 guibg=#555555 guifg=#ffffff " Matched brackets hi MatchParen ctermfg=7 ctermbg=4
首先改变colors_name,vim在某此情况会根据这个名字重新载入color scheme。
接下来的Pmenu
和PmenuSel
用来设置vim下拉菜单的颜色,我们在使用lookupfile插件
中看到过下拉菜单。
vim 7中,当光标移到括号上时,vim会高亮与之匹配的括号,所使用的颜色就是
MatchParen
,我在这里也更改这个颜色。
Pmenu
、PmenuSel
,以及MatchParen
,都是vim定义的缺省高亮组的名字,你可以用
:help highlight-groups
命令查看有这些高亮组及其含义。
如果你打算在终端及GUI界面中使用不同的colorscheme,可以这样设:
" color scheme if has("gui_running") colorscheme darkblue_my else colorscheme desert_my endif " has
vim还提供了一个脚本,可以把你的文件按当前的颜色定义转化成HTML/XML文件,试试
:TOhtml
命令吧,更多信息请:help 2html.vim
。
高亮当前的单词
记得Source Insight中有一个功能,按SHIFT+F8
可以把光标下的词高亮出来,
在看代码时非常有用。vim下也有一个插件可以完成此功能,而且比Source Insight的这个
功能强大多了。
这个插件由Yuheng Xie所写,对这个插件有什么疑问,可以水木社区的vim版找到他
(http://www.newsmth.net/bbsdoc.php?board=vim
)。
http://www.vim.org/scripts/script.php?script_id=1238下载此插件。
把此插件直接拷贝到你的.vim/plugin
目录就行了。
参考配置
我在vimrc中这样设置:
"""""""""""""""""""""""""""""" " mark setting """""""""""""""""""""""""""""" nmap <silent> <leader>hl <Plug>MarkSet vmap <silent> <leader>hl <Plug>MarkSet nmap <silent> <leader>hh <Plug>MarkClear vmap <silent> <leader>hh <Plug>MarkClear nmap <silent> <leader>hr <Plug>MarkRegex vmap <silent> <leader>hr <Plug>MarkRegex
这样,当我输入,hl
时,就会把光标下的单词高亮,在此单词上按,hh
会清除该单词的
高亮。如果在高亮单词外输入,hh
,会清除所有的高亮。
你也可以使用virsual模式选中一段文本,然后按,hl
,会高亮你所选中的文本;
或者你可以用,hr
来输入一个正则表达式,这会高亮所有符合这个正则表达式的文本。
你可以在高亮文本上使用,#
或,*
来上下搜索高亮文本。在使用了,#
或,*
后,就
可以直接输入#
或*
来继续查找该高亮文本,直到你又用#
或*
查找了其它文本。
如果你在启动vim后重新执行了colorscheme命令,或者载入了会话文件,那么mark插件的
颜色就会被清掉,解决的办法是重新source一下mark插件。或者像我一样,把mark插件
定义的highlight组加入到你自己的colorscheme文件中。例如,把下面的语句加到
desert_my.vim
及darkblue_my.vim
中:
" For mark plugin hi MarkWord1 ctermbg=Cyan ctermfg=Black guibg=#8CCBEA guifg=Black hi MarkWord2 ctermbg=Green ctermfg=Black guibg=#A4E57E guifg=Black hi MarkWord3 ctermbg=Yellow ctermfg=Black guibg=#FFDB72 guifg=Black hi MarkWord4 ctermbg=Red ctermfg=Black guibg=#FF7272 guifg=Black hi MarkWord5 ctermbg=Magenta ctermfg=Black guibg=#FFB3FF guifg=Black hi MarkWord6 ctermbg=Blue ctermfg=Black guibg=#9999FF guifg=Black
不知道为什么,我的vim 7.0在切换到其它缓冲区然后再切换回来时,原来被标记的文本会 失去高亮。而作者说他并不存在此问题。如果你存在类似的问题,可以打上我所加的补丁:
--- easwy/mark.vim 2006-12-01 13:02:18.000000000 +0800 +++ plugin/mark.vim 2007-03-23 10:22:02.000000000 +0800 @@ -440,6 +440,43 @@ endif endfunction +" easwy add +" return the mark string under the cursor. multi-lines marks not supported +function! <SID>RedoMarkWord() + " define variables if they don't exist + call s:InitMarkVariables() + + let i = 1 + while i <= g:mwCycleMax + if b:mwWord{i} != "" + " quote regexp with / etc. e.g. pattern => /pattern/ + let quote = "/?~!@#$%^&*+-=,.:" + let j = 0 + while j < strlen(quote) + if stridx(b:mwWord{i}, quote[j]) < 0 + let quoted_regexp = quote[j] . b:mwWord{i} . quote[j] + break + endif + let j = j + 1 + endwhile + if j >= strlen(quote) + return -1 + endif + + " highlight the word + exe "syntax clear MarkWord" . i + exe "syntax match MarkWord" . i . " " . quoted_regexp . " containedin=ALL" + endif + let i = i + 1 + endwhile +endfunction + +augroup markword + autocmd! + autocmd BufWinEnter * call <SID>RedoMarkWord() +augroup END +" easwy end + " Restore previous 'cpo' value let &cpo = s:save_cpo
用法:
-
保存该patch到某一目录,例如:
/tmp/mark.vim.patch
-
cd到你的.vim目录:
cd ~/.vim
-
运行命令:
cat /tmp/mark.vim.patch | patch -p0
compl-omni 补全
vim的OMNI补全(以下称」全能补全」)可以支持多种程序语言,包括C,C++, XML/HTML,CSS
,JAVASCRIPT,PHP,RUBY等,详细列表请参阅:help compl-omni-filetypes
。在本文中
,主要介绍C及C++的全能补全。
例如,我们在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-N和CTRL-P补全了。它们会在当前缓冲区、其它缓冲区,以及当前文件所包含的头文件中查找以光标前关键字开始的单词。智能补全不能对局部变量进行补全,而CTRL-N和CTRL-P补全则可以很好的胜任。
下图是采用CTRL-P补全的一个例子,输出字符」pa」,然后按CTRL-P,vim会在下拉菜单中列出所有的匹配功能供选择,此时再按一下CTRL-P,就选中了第一个项目,也就是我想输入的」parmp」。我们第一次输入CTRL-P的是进行补全,第二次输入的CTRL-P是在下拉菜单中向上选择,二者的含义是不同的。
我们知道,CTRL-P一般的含义是向上,因此CTRL-P补全是向上查找以进行补全,而CTRL-N是向下查找以进行补全,在不同场合使用不同的快捷键可以加速补全的速度。
使用CTRL-N和CTRL-P补全时,由’complete‘选项控制vim从哪些地方查找补全的内容。例如,对于比较大的软件项目,文件包含关系复杂,如果CTRL-N和CTRL-P补全时查找所包含的头文件,耗时会比较久。此时,可以在’complete‘选项中去掉’i‘标记,这样CTRL-N和CTRL-P补全就不在头文件中查找了,速度会快很多;当然,弊端就是你无法对头文件中出现的某些内容进行补全了。’complete‘选项中其它标记的含义,请阅读手册页。
vim中其它的补全方式包括:
-
整行补全
CTRL-X CTRL-L
-
根据当前文件里关键字补全
CTRL-X CTRL-N
-
根据字典补全
CTRL-X CTRL-K
-
根据同义词字典补全
CTRL-X CTRL-T
-
根据头文件内关键字补全
CTRL-X CTRL-I
-
根据标签补全
CTRL-X CTRL-]
-
补全文件名
CTRL-X CTRL-F
-
补全宏定义
CTRL-X CTRL-D
-
补全vim命令
CTRL-X CTRL-V
-
用户自定义补全方式
CTRL-X CTRL-U
-
拼写建议
CTRL-X CTRL-S
例如,当我们按下」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补全
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中那样,方便了很多!
调试:pyclewn
本节所用命令的帮助入口:
:help pyclewn
gvim在编译时需要使能netbeans_intg特性和autocmd特性。
安装pyclewn很简单,在我的计算机上,gvim安装目录在我的HOME目录,因此,也把 pyclewn安装在HOME目录,使用如下命令:
cd /home/easwy/download/pyclewn-0.7/ vimdir=$HOME/.vim python setup.py install --home=$HOME
使用
下面通过一个例子讲解一下如何使用pyclewn进行调试。例子中所调试的程序在这里下载:
http://easwy.com/blog/uploads/2009/10/pyclewn-ex.zip
首先启动pyclewn。启动pyclewn的办法很简单,在一个终端中执行下面的命令就可以了:
pyclewn
pyclewn启动时,它会启动一个gvim窗口,我们的调试将在这个gvim窗口中进行。运行pyclewn的终端将做为gdb的控制终端,所调试程序的输入输出都会通过这个终端进行(当然,你也可以在gdb中通过tty命令更改控制终端)。
接下来,我们在pyclewn所打开的gvim窗口中输入下面的命令,编译该程序,打开要调试的文件,并在文件中设置断点:
:cd pyclewn-ex :make :e main.c :Cfile factorial :Cbreak 14
前面三条命令是标准的vim命令,切换到示例程序所在目录,编译该程序,并打开文件main.c。后面两条命令以大写字母C做为起始,这是pyclewn自定义的命令,pyclewn将会把字母C后的命令内容传递给GDB调试器。所以上面两条命令相当于在GDB中执行file factor和break 14,加载factor做为被调试的程序,并在main.c的第14行设置一个断点。
在执行pyclewn自定义的C命令时,pyclewn会在gvim中分隔出一个窗口,用于显示GDB调试器的输入输出。所以,执行完上面命令后,屏幕看起来是这样的:
在上面已经设置好断点了,现在就可以开始调试了。pyclewn已经定义了一些调试相关的键映射,我们可以通过下面的命令加载这些键映射:
:Cmapkeys
执行完这条命令,会在clewn_console中打印出所定义的键映射,我在此不再赘述。在下面的调试过程中,我也会使用几个最常用的映射。
我们继续调试。我在上面已经定义了一个断点,所以直接按SHIFT-R键运行程序。程序运行到断点后会停下来,然后我们连按三次CTRL-N,执行三条语句,现在切换到控制终端,可以看到程序在等待输入,我们输入一个数字,然后按回车。现在看到的屏幕是这样的:
在上面的抓图中,我们把鼠标移动到变量n上,可以看到弹出了一个小气泡,显示变量n的值为4,这和我们输入的数字是一致的。
接下来再按一次CTRL-N向下执行一个语句,然后再按SHIFT-S步进到函数factorial()中,现在gvim会打开文件util/factorial.c。然后用下面的命令,把变量t和i加入到watch窗口中:
:Cdbgvar t :Cdbgvar i
上面的命令会创建一个名为(clewn)_dbgvar的缓冲区,不过此缓冲区并未显示出来。用下面的命令可以新建一个窗口显示此缓冲区:
:sb (clewn)_dbgvar
现在屏幕看起来是这样的:
按一次SHIFT-C使程序运行至结束,我们的调试也就告一段落了。
从上面的调试过程可以看出,使用pyclewn调试很方便。而且,使用pyclewn也可以在windows上进行调试,不过我没有试过,有兴趣的朋友可以试一下。在windows上调试,可能需要使用cygwin中所带的gdb。
如果觉得pyclewn缺省所设置的键映射不能满足自己的需求,也可以自己定义更多GDB调试键映射,方法是把pyclewn发行目录中的.clewn_keys.gdb拷贝到你的HOME目录,然后修改此文件定制自己的键绑定即可。
cd /home/easwy/download/pyclewn-0.7/ cp runtime/.clewn_keys.gdb $HOME
要想了解更多关于pyclewn的使用,请阅读pyclewn的帮助手册::help pyclewn
。