如何在Vim中使用ctags?之前在《把Vim打造成真正的IDE》系列里已经讲过大致的ctags在vim中的使用,这篇文章我们就详细的讲一下。 首先要明白,ctags是什么? 官方的解释是:
产生标记文件以帮助在源文件中定位对象。
其生成的标记文件tags中包括这些对象的列表:
用#define定义的宏 枚举型变量的值 函数的定义、原型和声明 名字空间(namespace) 类型定义(typedefs) 变量(包括定义和声明) 类(class)、结构(struct)、枚举类型(enum)和联合(union) 类、结构和联合中成员变量或函数
那么我们用怎样的参数来使ctags正常的生成我们需要的tags文件呢?在这里我们就不去挨个学习那些枯燥的参数了,直接参看 omnicppcomplete 提供的ctags生成语句:
ctags -R --c++-kinds=+px --fields=+iaS --extra=+q .
每个参数解释如下:
-R:ctags循环生成子目录的tags --c++-kinds=+px :ctags记录c++文件中的函数声明和各种外部和前向声明 --fields=+iaS :ctags要求描述的信息,其中i表示如果有继承,则标识出父类;a表示如果元素是类成员的话,要标明其调用权限(即是public还是private);S表示如果是函数,则标识函数的signature。 --extra=+q:强制要求ctags做如下操作—如果某个语法元素是类的一个成员,ctags默认会给其记录一行,可以要求ctags对同一个语法元素再记一行,这样可以保证在VIM中多个同名函数可以通过路径不同来区分。
OK,那么tags文件就生成好啦,利用这个文件我们可以做很多强大的事情,包括前面用过的插件,omnicppcomplete、taglist、showfunc之类的,都是依赖于它的。 那么除了插件上的作用外,我们用户在vim里面怎么使用他呢? 其实最简单的就是:
把光标移动到某个元素上,CTRL+],就会跳转到对应的定义啦。CTRL+o可以回退到原来的地方。
还有一个操作经常被人忽略,就是,如果当前光标下是个局部变量,在VIM里输入gd的话,就会跳到这个局部变量的定义处,也是非常方便滴~~ 另外,tags必须在vim运行的当前目录,才能在vim里面正确跳转,当然也不是没有办法解决:
set tags+=tags的文件路径
不过如果像我前面文章说的那样定义了F12来快速生成tags的话( 快速连接 ),也不会经常用到更改路径吧,哈哈。 顺便说一句,tags生成路径最好不要包含中文哦~~ OK,在Vim中使用ctags就到这里,下次我们会一起看看据说ctags的升级替代品,cscope~ 另附 ctags官方下载地址 ,目前最新版本为5.8 后记: 在用-R直接生成的tags的时候,如果无关的文件太多,tags生成的会非常而且慢,比如cocos2d-x的项目。
解决的方法比较简单,参考了cscope生成 cscope.files的思路:
find . -name "*.h" -o -name "*.c" -o -name "*.cpp" -o -name "*.m" -o -name "*.mm" -o -name "*.java" -o -name "*.py" > src.files
ctags -R --c++-kinds=+px --fields=+iaS --extra=+q -L src.files
这样生成的速度就会快很多啦
alex on #
最近在写多线程的代码,安装的插件和你的差不多,但是为什么当用ctrl+]跳转的时候,不能识别pthread_t, pthread_create, pthread_mutex_init等等其他函数呢?
不过在输入代码的时候,使用ctrl+n确实可以把这些函数很好的识别出来。不知道为什么。
希望能和博主交流一下
Reply
Dante on #
呃。。是这样的,ctrl+[要想能跳转,一定需要生成了对应的tags,这里你应该是没有生成的。
而对于ctrl+n可以补全,实际上vim是自动列出了你在vim中输入过的单词列表,你之前一定是输入过一遍,所以才会自动提示出来的~~
Reply
happypeter on #
`Ctrl-N` can also bring us whatever in `tags` file, check `:h i_CTRL-N` and `:h 'complete'`.
For more info, check this screencast:
http://happycasts.net/episodes/25
Reply
Dante on #
如果不清楚ctags怎么用,可以参考这篇文章
http://www.vimer.cn/2009/10/%e6%8a%8avim%e6%89%93%e9%80%a0%e6%88%90%e4%b8%80%e4%b8%aa%e7%9c%9f%e6%ad%a3%e7%9a%84ide2.html
Reply
alex on #
首先谢谢你,不过我使用的是vim 7.2,它对于我没有输入过的符号也是可以识别的,可以自动补全的,而且还会在它解析过的符号后注明该符号所在的文件,而我之前输入过的符号后面是什么都没有的。怀疑过是不是那个pthread.h文件没有解析,打开了那个tags文件,搜索了一下pthread.h还是存在的,而且它还是能够解析pthread_join等一些函数的,请问你的vim能够对这些符号进行解析吗?
Reply
Dante on #
呃,我没有用ctags把所有的系统头文件生成。。怕那样会变慢,但按理说应该不会有你这个问题的,能看一下你生成tags的命令?
Reply
alex on #
不好意思,提问的时候没有把问题都说清楚,我的生成命令修改了一下omnicppcomplete帮助文档里的命令 ctags -R --c++-kinds=+plx --fields=+iaS --extra=+q . 生成命令就是这个样子,在vimrc文件里按照他们的设置是set tags=/usr/include/tags,./tags,./..tags,./**/tags 后面这两个符号不是很明白,能否解释一下,谢谢
Reply
Dante on #
./..tags实在想不清楚想表达什么。
./**/tags应该标识所有子目录中的tags,具体没测试过。。
这里你只要关联上你生成的tags就行了,不用非要按照这个写的~
Reply
alex on #
不过实际的效果确实是我想要的,得到了很好的解析,但是那个pthread_create问题呢?如何才能正确解析呢?
Reply
Dante on #
在set tags里面设置了那个生成了pthread_create的tags了吗?
Reply
alex on #
pthread_create 是在/usr/include/pthread.h文件中的,我在/usr/include文件夹下执行那条命令,是解析了的,文件就是/usr/include/tags,不过好像没有解析似的。另外还发现了一个问题,指定了-R选项,好像并没有递归解析似的,这在我自己的写pthreadPool项目中感觉出来的
Reply
Dante on #
呃,-R应该是一定会递归解析的。。。我这里测试过的,生成了整个大项目。
对pthread_create找不到的问题,就真的不知道原因了。。
Reply
alex on #
能不能把你的vimrc和你安装的插件列表发给我,多谢
Reply
Dante on #
http://www.vimer.cn/2010/06/%E6%9C%AC%E5%8D%9A%E4%BD%BF%E7%94%A8%E7%9A%84vimgvim%E7%9B%B8%E5%85%B3%E6%8F%92%E4%BB%B6%E6%95%B4%E7%90%86.html
这是我之前特意整理的列表,希望对你有用。
Reply
ca on #
ctags -R --c++-kinds=+px --fields=+iaS --extra=+q .
这条命令在哪用?
看了好多文章,都说自动补齐需要生成tags文件,都说用
ctags -R --c++-kinds=+px --fields=+iaS --extra=+q .
可这个命令在哪用?
不好意思,刚接触VIM不久,我是在Windows环境下安装的,7.3,现在一直想让VIM能象VC一样实现自动提示成员变量的功能
不知道博主能否再讲解的详细一些,谢谢
Reply
Dante on #
这个命令是在命令行下面执行的。
ctags是个程序,如果在windows下,是需要自己下载安装的~
Reply
ca on #
搞明白了,谢谢博主
再问一个问题,我发现自动补全这个功能有些不太完美,但不知道怎么设置,比如有如下代码
class base
{
public:
int a;
};
base bs;
如果这时输入“bs.”的话,会提示出好大一堆参数,包括int, char,什么的,其中也包括a。
请问怎么设置下,让自动补全功能,只提示该类中的成员变量呢?
Reply
Dante on #
不会把,是用OmniCppComplete吗?
Reply
ca on #
对,完全按着博主那3篇打造IDE的文章做的
Reply
Dante on #
咦,那应该不会呀,提示的就是类的成员变量的~
Reply
Dante on #
是C-X C-O把?
Reply
ca on #
我之前是直接Ctrl-P
后来有一个插件,输入bs.后直接按Tab就可以提示了
Reply
Dante on #
用c-x c-o吧,才是全能补全,c-p补全是补全vimbuff中出现的单词,你用的那个插件的补全会综合所有的补全。
所以如果直线出类变量的话,用c-x c-o就好了。
Reply
ca on #
Option 'omnifunc' is not set
当我按下c-x,然后再按下c-o的时候,提示这个
Reply
Dante on #
这个应该是OmniCppComplete没设置好,确认打开了cpp文件,并且类的写法没有问题,并且当前目录已经生成好了tags
Reply
沧浪淼客 on #
以上命令在我的win7上不行啊。。只能产生一个说明性的tags文件。。我用的Ctags -R 这个命令。。注意C也是大写的。。
Reply
沧浪淼客 on #
现在还没整好。。在_vimrc文件中加入tags时还要注意路径的写法,不会啊。。不加引号提示出错。。
Reply
The Burn on #
您好,我想问一下,我现在用omini补全的时候用了pythoncomplete,用一些系统的东西能补全,但使用pyqt的时候没法补全,请问有办法么?
Reply
Dante on #
vim 7.3 对python的补全默认就很好呢。。不需要其他的补全工具了吧。。
Reply
The Burn on #
就是自带的一个插件么?pythoncomplete好像就是他自带的吧,我看过win下面的vim7.3里面是自带的,还有个python3complete,但是我用了pyqt做图形界面的时候就没法自动补全,python原生的还是能补全的!
Reply
i love you on #
请问有没有不用装ctags的tag插件,能简单分析下当前页面的就行
Reply
海纳百川 on #
原来还有这个神器,还一直说用vim无法提示,或补全呢。
Reply
卜你个头Geek on #
如果是一个大项目,当中有很多个类并且有很多同名的方法的话。一旦跳转 ctags 会列出整个项目中同名的方法的让你选,然后你在 ctags 列出的一大堆类文件名中去找你要跳转的类。我用了一次,给我列出了整个项目三十多个同名的方法,我差点就哭了。
不想因此而放弃 Vim, 不知是否有更好的解决方案我不知道。
Reply
Dante on #
嗯,这个确实没有那么智能。。
Reply