最后更新于 .

如何在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

这样生成的速度就会快很多啦

Pingbacks

  1. vim配置攻略-打造自己的IDE | Cherrot on #

    [...] 在Vim中使用ctags [...]

  2. 无所不能的vim——vim到底能做什么 | 农夫庄园 on #

    […] vim+tags+taglist即可轻松实现上面的功能,功能上完全可以替代si或者vs.详见:把VIM打造成一个真正的IDE(2),在Vim中使用ctags […]

Pingbacks已打开。

Trackbacks

引用地址

评论

  1. alex

    alex on #

    最近在写多线程的代码,安装的插件和你的差不多,但是为什么当用ctrl+]跳转的时候,不能识别pthread_t, pthread_create, pthread_mutex_init等等其他函数呢?

    不过在输入代码的时候,使用ctrl+n确实可以把这些函数很好的识别出来。不知道为什么。

    希望能和博主交流一下

    Reply

    1. Dante

      Dante on #

      呃。。是这样的,ctrl+[要想能跳转,一定需要生成了对应的tags,这里你应该是没有生成的。
      而对于ctrl+n可以补全,实际上vim是自动列出了你在vim中输入过的单词列表,你之前一定是输入过一遍,所以才会自动提示出来的~~

      Reply

      1. happypeter

        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

    2. Dante

      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

  2. alex

    alex on #

    首先谢谢你,不过我使用的是vim 7.2,它对于我没有输入过的符号也是可以识别的,可以自动补全的,而且还会在它解析过的符号后注明该符号所在的文件,而我之前输入过的符号后面是什么都没有的。怀疑过是不是那个pthread.h文件没有解析,打开了那个tags文件,搜索了一下pthread.h还是存在的,而且它还是能够解析pthread_join等一些函数的,请问你的vim能够对这些符号进行解析吗?

    Reply

    1. Dante

      Dante on #

      呃,我没有用ctags把所有的系统头文件生成。。怕那样会变慢,但按理说应该不会有你这个问题的,能看一下你生成tags的命令?

      Reply

      1. alex

        alex on #

        不好意思,提问的时候没有把问题都说清楚,我的生成命令修改了一下omnicppcomplete帮助文档里的命令 ctags -R --c++-kinds=+plx --fields=+iaS --extra=+q . 生成命令就是这个样子,在vimrc文件里按照他们的设置是set tags=/usr/include/tags,./tags,./..tags,./**/tags 后面这两个符号不是很明白,能否解释一下,谢谢

        Reply

        1. Dante

          Dante on #

          ./..tags实在想不清楚想表达什么。
          ./**/tags应该标识所有子目录中的tags,具体没测试过。。
          这里你只要关联上你生成的tags就行了,不用非要按照这个写的~

          Reply

          1. alex

            alex on #

            不过实际的效果确实是我想要的,得到了很好的解析,但是那个pthread_create问题呢?如何才能正确解析呢?

            Reply

            1. Dante

              Dante on #

              在set tags里面设置了那个生成了pthread_create的tags了吗?

              Reply

              1. alex

                alex on #

                pthread_create 是在/usr/include/pthread.h文件中的,我在/usr/include文件夹下执行那条命令,是解析了的,文件就是/usr/include/tags,不过好像没有解析似的。另外还发现了一个问题,指定了-R选项,好像并没有递归解析似的,这在我自己的写pthreadPool项目中感觉出来的

                Reply

                1. Dante

                  Dante on #

                  呃,-R应该是一定会递归解析的。。。我这里测试过的,生成了整个大项目。
                  对pthread_create找不到的问题,就真的不知道原因了。。

                  Reply

                  1. alex

                    alex on #

                    能不能把你的vimrc和你安装的插件列表发给我,多谢

                    Reply

                    1. Dante

                      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

  3. ca

    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

    1. Dante

      Dante on #

      这个命令是在命令行下面执行的。

      ctags是个程序,如果在windows下,是需要自己下载安装的~

      Reply

      1. ca

        ca on #

        搞明白了,谢谢博主
        再问一个问题,我发现自动补全这个功能有些不太完美,但不知道怎么设置,比如有如下代码
        class base
        {
        public:
        int a;
        };
        base bs;
        如果这时输入“bs.”的话,会提示出好大一堆参数,包括int, char,什么的,其中也包括a。
        请问怎么设置下,让自动补全功能,只提示该类中的成员变量呢?

        Reply

        1. Dante

          Dante on #

          不会把,是用OmniCppComplete吗?

          Reply

          1. ca

            ca on #

            对,完全按着博主那3篇打造IDE的文章做的

            Reply

            1. Dante

              Dante on #

              咦,那应该不会呀,提示的就是类的成员变量的~

              Reply

            2. Dante

              Dante on #

              是C-X C-O把?

              Reply

              1. ca

                ca on #

                我之前是直接Ctrl-P
                后来有一个插件,输入bs.后直接按Tab就可以提示了

                Reply

                1. Dante

                  Dante on #

                  用c-x c-o吧,才是全能补全,c-p补全是补全vimbuff中出现的单词,你用的那个插件的补全会综合所有的补全。
                  所以如果直线出类变量的话,用c-x c-o就好了。

                  Reply

                  1. ca

                    ca on #

                    Option 'omnifunc' is not set
                    当我按下c-x,然后再按下c-o的时候,提示这个

                    Reply

                    1. Dante

                      Dante on #

                      这个应该是OmniCppComplete没设置好,确认打开了cpp文件,并且类的写法没有问题,并且当前目录已经生成好了tags

                      Reply

      2. 沧浪淼客

        沧浪淼客 on #

        以上命令在我的win7上不行啊。。只能产生一个说明性的tags文件。。我用的Ctags -R 这个命令。。注意C也是大写的。。

        Reply

        1. 沧浪淼客

          沧浪淼客 on #

          现在还没整好。。在_vimrc文件中加入tags时还要注意路径的写法,不会啊。。不加引号提示出错。。

          Reply

  4. The Burn

    The Burn on #

    您好,我想问一下,我现在用omini补全的时候用了pythoncomplete,用一些系统的东西能补全,但使用pyqt的时候没法补全,请问有办法么?

    Reply

    1. Dante

      Dante on #

      vim 7.3 对python的补全默认就很好呢。。不需要其他的补全工具了吧。。

      Reply

      1. The Burn

        The Burn on #

        就是自带的一个插件么?pythoncomplete好像就是他自带的吧,我看过win下面的vim7.3里面是自带的,还有个python3complete,但是我用了pyqt做图形界面的时候就没法自动补全,python原生的还是能补全的!

        Reply

  5. i love you

    i love you on #

    请问有没有不用装ctags的tag插件,能简单分析下当前页面的就行

    Reply

  6. 海纳百川

    海纳百川 on #

    原来还有这个神器,还一直说用vim无法提示,或补全呢。

    Reply

  7. 卜你个头Geek

    卜你个头Geek on #

    如果是一个大项目,当中有很多个类并且有很多同名的方法的话。一旦跳转 ctags 会列出整个项目中同名的方法的让你选,然后你在 ctags 列出的一大堆类文件名中去找你要跳转的类。我用了一次,给我列出了整个项目三十多个同名的方法,我差点就哭了。
    不想因此而放弃 Vim, 不知是否有更好的解决方案我不知道。

    Reply

    1. Dante

      Dante on #

      嗯,这个确实没有那么智能。。

      Reply

发表评论