Vim

Cscope

Cscope 的功能比 ctags 要完善,但是只支持 C(通过设置 cscope.files 后同样支持 C++以及 Java)。鉴于 Tag 文件只是知道某个符号是在哪里定义的,cscope 的数据库里的数据信息就多的多了:

  • 符号是在哪里定义的?
  • 符号是在哪里被使用的?
  • 这个全局符号定义了什么?
  • 这个变量是在哪里被赋值的?
  • 这个函数在源文件的哪个位置?
  • 哪些函数调用了这个函数?
  • 这个函数调用了哪些函数?
  • "out of space"消息是从哪来的?
  • 在目录结构中当前的源文件在哪个位置?
  • 哪些文件引用了这个头文件?

1. 构建数据库

在你项目的根目录执行下面的命令:

$ cscope -bqR

这条命令会在当前目录下创建三个文件:cscope{,.in,.po}.out 。把它们想象成你的数据库。

不幸的时 cscope 默认只分析 *.[c|h|y|l] 文件。如果你想在 Java 项目中使用 cscope ,需要这样做:

$ find . -name "*.java" > cscope.files
$ cscope -bq

2. 添加数据库

打开你新创建的数据库连接:

:cs add cscope.out

检查连接已经创建成功:

:cs show

(当然你可以添加多个连接。)

3. 查询数据库

:cs find <kind> <query>

如::cs find d foo 会列出 foo(...) 调用的所有函数。

Kind 说明
s s ymbol:查找使用该符号的引用
g g lobal:查找该全局符号的定义
c c alls:查找调用当前方法的位置
t t ext:查找出现该文本的位置
e e grep:使用 egrep 搜索当前单词
f f ile:打开文件名
i i ncludes:查询引入了当前文件的文件
d d epends:查找当前方法调用的方法

推荐一些比较方便的映射,如:

nnoremap <buffer> <leader>cs :cscope find s  <c-r>=expand('<cword>')<cr><cr>
nnoremap <buffer> <leader>cg :cscope find g  <c-r>=expand('<cword>')<cr><cr>
nnoremap <buffer> <leader>cc :cscope find c  <c-r>=expand('<cword>')<cr><cr>
nnoremap <buffer> <leader>ct :cscope find t  <c-r>=expand('<cword>')<cr><cr>
nnoremap <buffer> <leader>ce :cscope find e  <c-r>=expand('<cword>')<cr><cr>
nnoremap <buffer> <leader>cf :cscope find f  <c-r>=expand('<cfile>')<cr><cr>
nnoremap <buffer> <leader>ci :cscope find i ^<c-r>=expand('<cfile>')<cr>$<cr>
nnoremap <buffer> <leader>cd :cscope find d  <c-r>=expand('<cword>')<cr><cr>

所以 :tag (或 ``)跳转到标签定义的文件,而 :cstag 可以达到同样的目的,同时还会打开 cscope 的数据库连接。'cscopetag' 选项使得 :tag 命令自动的像 :cstag 一样工作。这在你已经使用了基于标签的映射时会非常方便。

帮助文档::h cscope