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