转载:http://blog.csdn.net/Michael_Mao/archive/2007/09/27/1803516.aspx
"ctags"是一个独立的程序,绝大多数Unix系统上都会预装这个程序。
1、使用tags
tag是什么?一个位置。它记录了关于一个标识符在哪里被定义的信息,比如C或C++程序中的一个函数定义。这种tag聚集在一起被放入一个tags文件。这个文件可以让Vim能够从任何位置起跳达到tag所指示的位置-标识符被定义的位置。
下面的命令可以为当前目录下的所有C程序文件生成对应的tags文件:
(shell command) ctags *.c 现在你在Vim中要跳到一个函数的定义(如startlist)就可以用下面的命令:
(ex command) :tag startlist这个命令会带你到函数"startlist"的定义处,哪怕它是在另一个文件中。
CTRL+] 命
令会取当前光标下的word作为tag的名字并直接跳转。这使得在大量C程序中进行探索更容易一些。假设你正看函数"write
block",发现它调用了一个叫"write
line"的函数,这个函数是干什么的呢?你可以把光标置于"write_line"上,按下CTRL+]
即可。如果"write_line"函数又调用了 "write_
char".你当然又要知道这个函数又是什么功能。同时,置光标于"write_char"上按下CTRL+]。现在你位于函数"write_char"
的定义处。
":tags"命令会列出现在你就已经到过哪些tag了:
(ex command):
tags # TO tag FROM line in file/text
1 1 write_line 8 write_block.c
2 1 write_char 7 write_line.c
现在往回走。
CTRL+T命
令会跳到你前一次的tag处。在上例中它会带你到调用了"write_char"的"write_line"函数的地方。CTRL+T可以带一个命令记
数, 以此作为往回跳的次数, 你已经向前跳过了,现在正在往回跳,我们再往前跳一次。下面的命令可以直接跳转到当前tag序列的最后:
(ex command) :tag你也可以给它一个前辍, 让它向前跳指定的步长. 比如"
:3tag"。CTRL+T也可以带一个前辍。这些命令可以让你向下深入一个函数调用树(使用CTRL+]), 也可以回溯跳转(使用CTRL+T). 还可以随时用":tags"看你当前的跳转历史记录。
2、分隔窗口
":tag"命令会在当前窗口中载入包含了目标函数定义的文件。但假设你不仅要查看新的函数定义,还要同时保留当前的上下文呢?你可以在":tag"后使用一个分隔窗口命令":split"。Vim还有一个一举两得的命令:
(ex command) :stag tagname要分隔当前窗口并跳转到光标下的tag:
(normal mode command) CTRL+W+]如果同时还指定了一个命令记数, 它会被当作新开窗口的行高.
3、多个tags文件
如果你的源文件位于多个目录下,你可以为每个目录都建一个tags文件。Vim会在使用某个目录下的tags文件进行跳转时只在那个目录下跳转。
要使用更多tags文件,可以通过改变'tags'选项的设置来引入更多的tags文件。如:
(ex command) :set tags=./tags, ./../tags, ./*/tags这
样的设置使Vim可以使用当前目录下的tags文件,上一级目录下的tags文件,以及当前目录下所有层级的子目录下的tags文件。这样可能会引入很多
的tags文件,但还有可能不敷其用。比如说你正在编辑"~/proj/src"下的一个文件,但又想使用"~/proj/sub/tags"作为
tags文件。对这种Vim情况提供了一种深度搜索目录的形式。如下:(ex command) :set tags=~/proj/**/tags
4、单个tags文件
Vim在搜索众多的tags文件时,你可能会听到你的硬盘在咔嗒咔嗒拼命地叫。显然这会降低速度。如果这样还不如花点时间生成一个大一点的tags文件。这需要一个功能丰富的ctags程序,比如上面提到的那个。它有一个参数可以搜索整个目录树:
(shell command)cd ~/proj
ctags -R 用一个功能更强的ctags的好处是它能处理多种类型的文件。不光是C和C++源程序,也能对付Eiffel或者是Vim脚本。你可以参考ctags程序的文件调整自己的需要。现在你只要告诉Vim你那一个tags文件在哪就行了:
(ex command) :set tags=~/proj/tags
5、同名tag
当一个函数被多次重载(或者几个类里都定义了一些同名的函数),":tag"命令会跳转到第一个符合条件的。如果当前文件中就有一个匹配的,那又会优先使用它。当然还得有办法跳转到其它符合条件的tag去:
(ex command) :tnext重复使用这个命令可以发现其余的同名tag。如果实在太多,还可以用下面的命令从中直接选取一个:
(ex command) :tselect tagnameVim会提供给你一个选择列表,例如:(Display)
# pri kind tag file
1 F f mch_init os_amiga.c
mch_init()
2 F f mch_init os_mac.c
mch_init()
3 F f mch_init os_msdos.c
mch_init(void)
4 F f mch_init os_riscos.c
mch_init()
Enter nr of choice (
to abort):
现在你只需键入相应的数字(位于第一栏的)。 其它栏中的信息是为了帮你作出决策的。在多个匹配的tag之间移动,可以使用下面这些命令:
(ex command):tfirst go to first match
:[count]tprevious go to [count] previous match
:[count]tnext go to [count] next match
:tlast go to last match
如果没有指定[count],默认是1。
6、tag的名字
命令补齐真是避免键入一个长tag名的好办法。只要输入开头的几个字符然后按下制表符:
(ex command) :tag write_
Vim 会为你补全第一个符合的tag名。如果还不合你意,接着按制表符直到找到你要的。有时候你只记得一个tag名的片段,或者有几个tag开头相同。这里你可以用一个模式匹配来告诉Vim你要找的tag。
假设你想跳转到一个包含"block"的tag。首先键入命令:(ex command) :tag
/block。现在使用命令补齐:按。Vim会找到所有包含"block"的tag并先提供给你第一个符合的。"/"告诉Vim下
面的名字不是一五一十的tag名,而是一个搜索模式。通常的搜索技巧都可以用在这里。比如你有一个tag以"write "开始:(ex
command) :tselect /
^write_,"^"表示这个tag以"write_"开始。不然在半中间出现write的tag也会被搜索到。同样"$"可以用于告诉Vim要查找的
tag如何结束。
7、tags的浏览器
CTRL+]可以直接跳转到以当前光标下的word为tag名的地方去,所以可以在一个tag列表中使用它。下面是一个例子。首先建立一个标识符的列表(这需要一个好的ctags):
(shell command) ctags --c-types=f -f functions *.c
现在直接启动Vim, 以一个垂直分隔窗口的编辑命令打开生成的文件:
(shell command) vim:vsplit functions
这个窗口中包含所有函数名的列表。可能会有很多内容,但是你可以暂时忽略它。用一个":setlocal ts=99"命令清理一下显示。在该窗口中,定义这样的一个映射:
(ex command):nnoremap 0yew:tag "
现在把光标移到你想要查看其定义的函数名上,按下回车键,Vim就会在另一个窗口中打开相应的文件并定位到到该函数的定义上。
8、其它相关主题
设置'ignorecase'也可以让tag名的处理忽略掉大小写。'tagsearch'选项告诉Vim当前参考的tags文件是否是排序过的。默认情
况假设该文件是排序过的,这会使tag的搜索快一些,但如果tag文件实际上没有排序就会在搜索时漏掉一些tag。
'taglength'告诉Vim一个tag名字中有效部分的字符个数。例:
#include
int very_long_variable_1;
int very_long_variable_2;
int very_long_variable_3;
int very_long_variable_4;
int main()
{
very_long_variable_4 = very_long_variable_1 *
very_long_variable_2;
}
对于上面这段代码, 4个变量长度都为20, 如果将'taglength'设为10, 则:
(ex command):tag very_long_variable_4
会匹配到4个tag,而不是1个,光标停留在very_long_variable_1所在行上,因为被搜索的tag部分只有前面的10个字符: "very_long_",相应的显示是(是gvim中文版的真正显示,不是翻译的):
(Display)找到tag: 1/4 或更多
cscope使用
打开vim的配置文件:sudo gedit /etc/vim/vimrc;然后在该文件下添加如下代码:
Taglist 安装使用
本节所用命令的帮助入口:
:help helptags
:help taglist.txt
介绍了在vim中如何使用tag文件,本文主要介绍如何使用taglist插件(plugin)。
想必用过Source
Insight的人都记得这样一个功能:SI能够把当前文件中的宏、全局变量、函数等tag显示在Symbol窗口,用鼠标点上述tag,就跳到该tag
定义的位置;可以按字母序、该tag所属的类或scope,以及该tag在文件中出现的位置进行排序;如果切换到另外一个文件,Symbol窗口更新显示
这个文件中的tag。
在vim中的taglist插件所实现的就是上述类似的功能,有些功能比SI弱,有些功能比SI更强。而且,taglist插件还在不断完善中!
要使用taglist plugin,必须满足:
-
打开vim的文件类型自动检测功能:filetype on
-
系统中装了工具,并且taglist plugin能够找到此工具(因为taglist需要调用它来生成tag文件)
-
你的vim支持system()调用
在文章vimrc初步中,我们使用了vim自带的示例vimrc,这个vimrc中已经打开了文件类型检测功能;在上篇文章中,我们也已用到了Exuberant ctags;system()调用在一般的vim版本都会支持(suse Linux发行版中出于安全考虑,关闭了此功能),所以我们已经满足了这三个条件。
现在我们到下载最新版本的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窗口,你从中可以看到在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窗口中,可以使用下面的快捷键:
跳到光标下tag所定义的位置,用鼠标双击此tag功能也一样
o 在一个新打开的窗口中显示光标下tag
显示光标下tag的原型定义
u 更新taglist窗口中的tag
s 更改排序方式,在按名字排序和按出现顺序排序间切换
x taglist窗口放大和缩小,方便查看较长的tag
+ 打开一个折叠,同zo
- 将tag折叠起来,同zc
* 打开所有的折叠,同zR
= 将所有tag折叠起来,同zM
[[ 跳到前一个文件
]] 跳到后一个文件
q 关闭taglist窗口
显示帮助
可以用”:TlistOpen“打开taglist窗口,用”:TlistClose“关闭taglist窗口。或者使用”:TlistToggle“在打开和关闭间切换。在我的vimrc中定义了下面的映射,使用键就可以打开/关闭taglist窗口:
map :TlistToggle
Taglist插件还提供了很多命令,你甚至可以用这些命令创建一个taglist的会话,然后在下次进入vim时加载此会话。
taglist 的配置
为了让taglist窗口更加适合不同人的开发,可以在vim的配置文件 ~/.vimrc 中进行一些配置
- Tlist_GainFocus_On_ToggleOpen : #为1则使用TlistToggle打开标签列表窗口后会获焦点至于标签列表窗口;为0则taglist打开后焦点仍保持在代码窗口
-
Tlist_Auto_Open # 为1则Vim启动后自动打开标签列表窗口
-
Tlist_Close_On_Select : # 选择标签或文件后是否自动关闭标签列表窗口
-
Tlist_Exit_OnlyWindow : #Vim当前仅打开标签列表窗口时,是否自动退出Vim
-
Tlist_Use_SingleClick : #是否将默认双击标答打开定义的方式更改为单击后打开标签
-
Tlist_Auto_Highlight_Tag : #是否高亮显示当前标签。命令":TlistHighlightTag"也可达到同样效果
-
Tlist_Highlight_Tag_On_BufEnter : #
默认情况下,Vim打开/切换至一个新的缓冲区/文件后,标签列表窗口会自动将当前代码窗口对应的标签高亮显示。
TlistHighlight_Tag_On_BufEnter置为0可禁止以上行为
-
Tlist_Process_File_Always : #为1则即使标签列表窗口未打开,taglist仍然会在后台处理vim所打开文件的标签
-
Tlist_Auto_Update :
#打开/禁止taglist在打开新文件或修改文件后自动更新标签。禁止自动更新后,taglist仅在使
用:TlistUpdate,:TlistAddFiles,或:TlistAddFilesRecursive命令后更新标签
-
Tlist_File_Fold_Auto_Close : #自动关闭标签列表窗口中非激活文件/缓冲区所在文档标签树,仅显示当前缓冲区标签树
-
Tlist_Sort_Type : #标签排序依据,可以为"name"(按标签名排序)或"order"(按标签在文件中出现的顺序,默认值)
-
Tlist_Use_Horiz_Window : #标签列表窗口使用水平分割样式
-
Tlist_Use_Right_Window : #标签列表窗口显示在右侧(使用垂直分割样式时)
-
Tlist_WinWidth : #设定水平分割时标签列表窗口的宽度
-
Tlist_WinHeight : #设定垂直分割时标签列表窗口的高度
-
Tlist_Inc_Winwidth : #显示标签列表窗口时允许/禁止扩展Vim窗口宽度
-
Tlist_Compact_Format : #减少标签列表窗口中的空白行
-
Tlist_Enable_Fold_Column : #是否不显示Vim目录列
-
Tlist_Display_Prototype : #是否在标签列表窗口用标签原型替代标签名
-
Tlist_Display_Tag_Scope : #在标签名后是否显示标签有效范围
-
Tlist_Show_Menu : #在图型界面Vim中,是否以下拉菜单方式显示当前文件中的标签
-
Tlist_Max_Submenu_Item : #子菜单项上限值。如子菜单项超出此上限将会被分隔到多个子菜单中。缺省值为25
-
Tlist_Max_Tag_Length : #标签菜单中标签长度上限
阅读(2289) | 评论(3) | 转发(1) |