关闭

使用ctags

943人阅读 评论(0) 收藏 举报
    "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 tagname,Vim会提供给你一个选择列表,例如:(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 (<CR> 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_<Tab>Vim会为你补全第一个符合的tag名。如果还不合你意,接着按制表符直到找到你要的。有时候你只记得一个tag名的片段。或者有几个tag开头相同。这里你可以用一个模式匹配来告诉Vim你要找的tag。假设你想跳转到一个包含"block"的tag。首先键入命令:(ex command) :tag /block现在使用命令补齐:按<Tab>。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 <buffer> <CR> 0ye<C-W>w:tag <C-R>"<CR>
    现在把光标移到你想要查看其定义的函数名上,按下回车键,Vim就会在另一个窗口中打开相应的文件并定位到到该函数的定义上。
8、其它相关主题
    设置'ignorecase'也可以让tag名的处理忽略掉大小写。'tagsearch'选项告诉Vim当前参考的tags文件是否是排序过的。默认情况假设该文件是排序过的,这会使tag的搜索快一些,但如果tag文件实际上没有排序就会在搜索时漏掉一些tag。'taglength'告诉Vim一个tag名字中有效部分的字符个数。
例:
#include <stdio.h>
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 或更多
 
0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1274次
    • 积分:27
    • 等级:
    • 排名:千里之外
    • 原创:1篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档
    阅读排行
    评论排行