vi/Vim + Cscope/Ctags

使用vim + cscope/ctags,就可以实现SourceInsight的功能,以后可以不再用盗版SouceInsight读代码了。
按照vim里cscope的参考手册(在vim中执行”:help cscope”命令),把cscope功能加到.vimrc里后(需要你的vim在编译时选择了”–enable-cscope”选项,否则你需要重新编译vim),配置就算完成了。然后用下面的命令生成代码的符号索引文件:

    cscope -Rbkq


这个命令会生成三个文件:cscope.out, cscope.in.out, cscope.po.out。
其中cscope.out是基本的符号索引,后两个文件是使用”-q”选项生成的,可以加快cscope的索引速度。
上面所用到的命令参数,含义如下:

-R: 在生成索引文件时,搜索子目录树中的代码
-b: 只生成索引文件,不进入cscope的界面
-k: 在生成索引文件时,不搜索
/usr/include目录
-q: 生成cscope
.in.out和cscope.po.out文件,加快cscope的索引速度

接下来,就可以在vim里读代码了。
不过在使用过程中,发现无法找到C++的类、函数定义、调用关系。仔细阅读了cscope的手册后发现,原来cscope在产生索引文件时,只搜索类型为C, lex和yacc的文件(后缀名为.c, .h, .l, .y),C++的文件根本没有生成索引。不过按照手册上的说明,cscope支持c++和Java语言的文件。
于是按照cscope手册上提供的方法,先产生一个文件列表,然后让cscope为这个列表中的每个文件都生成索引。
为了方便使用,编写了下面的脚本来更新cscope和ctags的索引文件:

#!/bin/sh

find . -name "*.h" -o -name "*.c"-o -name "*.cc" > cscope.files
cscope -bkq -i cscope.files
ctags -R


这个脚本,首先使用find命令,查找当前目录及子目录中所有后缀名为”.h”, “.c”和”.cc”的文件,并把查找结果重定向到文件cscope.files中。
然后cscope根据cscope.files中的所有文件,生成符号索引文件。
最后一条命令使用ctags命令,生成一个tags文件,在vim中执行”:help tags”命令查询它的用法。它可以和cscope一起使用。

目前只能在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/

在vim的网站上,有很多和cscope相关的插件,可以去找一下你有没有所感兴趣的。搜索结果在这里: 点这里

另外,我的vim使用进阶系列文章介绍了vim的更多特性。

“vi/Vim + Cscope/Ctags”的18个回复

  1. @LiTuX, 你看看ctags的”-I”选项是否可以解决你的问题。
    不过ctags不是编译预处理程序,估计解决不了这种问题。你也可以试一下GNU Global,看看是否具有这种能力。

  2. 易水兄,在用 ctags 时一直有个问题不知道如何解决:ctags 由于对 C 中的宏定义大部分没有展开操作,因此当某些元素(比如函数声明)处出现宏定义时会无法识别 token 进而无法得到正确的 tags。比如针对下述代码:
    #include

    #define __NOTHING
    #define __PREFIX_FUN(f) __MY_PREFIX_##f

    int func(void) __NOTHING ;

    int __PREFIX_FUN(func) (void)
    {
    return printf(“In function `%s’ in %s: line %d.\n”, __func__, __FILE__, __LINE__);
    }

    int main(int argc, char *argv[])
    {
    func();
    __MY_PREFIX_func();
    return 0;
    }

    int func(void)
    {
    return printf(“In function `%s’ in %s: line %d.\n”, __func__, __FILE__, __LINE__);
    }
    /* EOF */
    ctags 无法解析 func 的函数声明,而且 __MY_PREFIX_func 函数的定义也无法正确解析,被错认为是 func 函数。

    这些问题不是我瞎编乱造的,因为在用 MinGW 时,发现它的库函数中很多都带有类似的宏,这造成的直接效果是在 vim 中甚至连 strlen 这样简单的函数都无法补全出来(因而猜测应该有更多),而 printf 之类会出现好多入口。

    所以,——有没有解决方法?或者有没有优于 ctags 的工具存在?

  3. 请问一下,我用cscope找到标示符后,进行选择的时候,提示文件不存在,这是怎么回事?还有,我自己重新定义了cscope_maps.vim的映射按键,但是并不管用。

  4. 使用这两行时,出现cscope:cannot find file 的提示信息:
    find . -name “*.h” -o -name “*.c”-o -name “*.cc” > cscope.files
    cscope -bkq -i cscope.files

    cscope: cannot find file src/platform/wce/123.c

    在cscope.files中可以找到这个src/platform/wce/123.c文件,请问这个是什么原因呢?谢谢!

  5. @hy
    文件中的代码,其实是html中的<pre>标记,你可以使用css控制它的显示格式。一般的主题里都会定义相应的格式的,你根据自己的需要改一下即可。

  6. 感谢博主的关于vim系列的文章。
    作为还没入门的人,读了很受用。
    也很喜欢,博主文章中的一些代码,命令的排版。
    我也有自己的一个blog,想写一下我学习的过程。对此,我想问一下,文章中的代码和命令的框框,是如何生成的。是跟主题关系,还是有什么技巧,我没有掌握。
    谢谢!

  7. (以下为CSDN评论的转帖)

    #leo 发表于2006-11-09 14:42:00 IP: 57.73.18.*
    在/usr/src/linux 目录下用了cscope -Rbkq,
    然后我在~/work/目录下新建了一个work.c, 为什么还是不能查找内核里的函数呢?

    #easwy 发表于2006-11-10 10:37:00 IP: 213.70.90.*
    你需要在vim中连接cscope的索引数据库,使用命令:
    :cs add /usr/src/linux/cscope.out

    使用”:help cscope”查看更多详细信息。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注