vim+cscope使用指南

简介

cscope是一款用于浏览C源码的工具,类似于ctags,但强大得多。

下文以leveldb代码库为例,讲述cscope的使用方法。

创建cscope数据库

在代码库的根目录下执行:

$ cscope -Rbq

将产生cscope.out、cscope.in.out和cscope.po.out三个文件。
各个选项的含义如下:
-b:仅构建交叉引用(cross-reference)文件,即数据库,然后退出,而不会进入下面的交互界面:
image
-R:递归解析所有的子目录。
-q:通过倒排索引加速符号的查找过程。该选项会导致cscope额外产生cscope.in.out和cscope.po.out两个文件。

$ file cscope.out 
cscope.out: cscope reference data version 15 with inverted index

相关命令

所有的cscope命令都以:cscope(:cs)开头。:表示这些命令均在vim的一般模式下执行。

以下逐一介绍cscope的子命令。

add(增加一个新的cscope数据库/连接)

用法

:cs add {file|dir} [pre-path] [flags]

例子

# 当前在./table目录,把根目录下的cscope.out加进来:
:cs add ../cscope.out /home/xhb/code/os/test-leveldb/leveldb-master -C
# 此时执行查找操作,会得到两个匹配项:
# /home/xhb/code/os/test-leveldb/leveldb-master/include/leveldb/table_builder.h
# /home/xhb/code/os/test-leveldb/leveldb-master/table/table_builder.cc

匹配项中的/home/xhb/code/os/test-leveldb/leveldb-master即为add指定的pre-path参数,而-C指定了搜索时忽略大小写。

如果不指定pre-path呢?

:cs add ../cscope.out
# 则查找结果就是:
# include/leveldb/table_builder.h
# table/table_builder.cc

如果当前目前下有cscope.out文件,则打开vim时会自动加载该数据库。

只有把cscope数据库加到vim中,才能进行后续的find操作。

find(查找)

用法

cs find {querytype} {name}

querytype(!!)
0或s:查找这个(指name参数,下同)C符号。
1或g:查找这个定义。
2或d:查找被这个函数调用的函数。
3或c:查找调用该函数的函数。
4或t:查找这个文本字符串。
6或e: 查找这个egrep的pattern。
7或f:查找这个文件。
8或i:查找#include了这个文件的所有文件。

除了4和6,其他类型下的name参数前面的空格都被忽略。
如果匹配项只有一个,则直接跳转到那里;如果有多个,则可以选择跳到哪一个。

例子

查找文件名中包含builder的文件:

:cs find f builder
# 结果如下:
Cscope tag: builder
   #   line  filename / context / line
   1      1  db/builder.cc <<<unknown>>>
   2      1  db/builder.h <<<unknown>>>
   3      1  include/leveldb/table_builder.h <<<unknown>>>
   4      1  table/block_builder.cc <<<unknown>>>
   5      1  table/block_builder.h <<<unknown>>>
   6      1  table/table_builder.cc <<<unknown>>>

对于#include的头文件,如果在当前目录下找不到,cscope甚至会搜索标准目录(/usr/include/等)。比如:

:cs find f stdlib.h
# 结果如下:
Cscope tag: stdlib.h
   #   line  filename / context / line
   1      1  /usr/include/stdlib.h <<<unknown>>>
   2      1  /usr/include/bits/stdlib.h <<<unknown>>>

基于当前光标所在处的单词进行查找:

# 当前光标停留在filter_policy上
:cs find f <cfile>
# 直接跳转到include/leveldb/filter_policy.h

# 当前光标停留在WriteBlock上
:cs find t <cword>
# 效果等同于:cs find t WriteBlock

其他辅助用法

Ctrl-t(!!)

假设A调用了B,B调用了C,我们刚开始在A处,通过:cs find g B跳到了B的定义,再跳到了C的定义,则通过Ctrl-t,我们可以回到B,再回到A。这里实际上维护了一个栈。

:scscope(:scs)(!!)

与:cs做的事情一样,但它会有分屏的效果。

# 水平分屏
:scs find f block_builder.cc
# 垂直分屏
:vert scs find f table_builder.cc

对于多个分屏的窗口,常用的操作有:
Ctrl-w Ctrl-w:在不同窗口间跳转。
hide:关闭当前窗口。
only:仅保留当前窗口。

show(显示所有的cscope连接)

:cs show
# 结果如下:
 # pid    database name                       prepend path
 0 8380   cscope.out                          <none>

8380为cscope进程的ID,通过ps可以看到vim进程为cscope进程的父进程,通过lsof可以看到它们之间通过pipe通信。

kill(断开cscope连接)

:cs show
# 结果如下:
 # pid    database name                       prepend path
 0 8380   cscope.out                          <none>
# 则可以这样断开该连接:
:cs kill 0
# 而断开全部连接是这样:
:cs kill -1

reset(重新初始化所有cscope连接)

cscope选项

使用:set设置所有的选项。理想的做法是在启动文件(如.vimrc)中做这件事,因为一些cscope变量只在.vimrc中有效,vim启动后再设置它们将没有效果。

cscopeprg(csprg)

指定执行cscope的命令,默认就是"cscope"。比如:

:set csprg=/usr/bin/cscope。

cscopequickfix(csqf)

是否使用quickfix窗口显示cscope的结果。需要在编译vim时指定+quickfix,才能启用该选项。默认值为""。
比如:set cscopequickfix=s-,c-,d-,i-,t-,e-,s/c/d/i/t/e即:cs find的querytype,其后的标志可以有+(将结果追加到quickfix窗口)、-(清空上一次的结果)、0(不使用quickfix。这里对于querytype=f,没有指定也相当于标志为0)。

例子

对于querytype=f,不指定标志时:

:set cscopequickfix=s-,c-,d-,i-,t-,e-
# 没有对querytype=f指定使用quickfix窗口,所以:cs find f builder的结果以位置列表(location list)的方式显示
Cscope tag: builder
   #   line  filename / context / line
   1      1  builder.cc <<<unknown>>>
   2      1  builder.h <<<unknown>>>
   3      1  table_builder.h <<<unknown>>>
   4      1  block_builder.cc <<<unknown>>>
   5      1  block_builder.h <<<unknown>>>
   6      1  table_builder.cc <<<unknown>>>

对于querytype=f,指定标志为-时:

:set cscopequickfix=s-,c-,d-,i-,t-,e-,f-
# 此时执行:cs find f builder,在vim窗口底部会显示:
(1 of 6): <<<unknown>>>

使用quickfix窗口的好处是,可以在搜索结果的多个匹配项间进行跳转,而位置列表的方式则只能选择一个项。
关于多个quickfix窗口的命令,常用的如下(!!):

:cnext/:cn:切换到下一个。
:cprev/:cp:切换到上一个。
:clist:列出所有项。
:cr:切换到第一个。
:cla:切换到最后一个。

对于querytype=f,指定标志为+时:

:set cscopequickfix=s-,c-,d-,i-,t-,e-,f+
# 则:cs find f builder每次的结果都会“累加”,比如执行10次就会有6*10=60个匹配项

cscopetag(cst)

设置之后,:tag/Ctrl-]/vim -t将使用:cstag,而不是默认的:tag,即cscope数据库和tag文件均用于搜索。

:set cst  # :set nocst(默认)

在cscope数据库中搜索时,:cstag和:cs find g等价;在tag文件中搜索时,:cstag和:tjump等价。

cscopetagorder/csto

指定:cstag的搜索顺序。0表示先搜索cscope数据库,若不匹配,再搜索tag文件,1则相反。

:set csto=1  # 默认为0

cscopeverbose/csverb

若不设置(默认),则增加cscope数据库时,将不会打印成功或失败信息。

:set csverb
:set nocsverb

cscopepathcomp/cspc

指定在查找结果中显示多少级文件路径。默认值0表示显示全路径(不是linux系统的全路径,比如如果没有设置pre-path,则block_builder.cc的全路径是table/block_builder.cc),1表示只显示文件名,等等。

例子:

:set cspc=3
# :cs find f table_builder的查找结果:
Cscope tag: table_builder
   #   line  filename / context / line
   1      1  include/leveldb/table_builder.h <<<unknown>>>
   2      1  table/table_builder.cc <<<unknown>>>
:set cspc=1
# :cs find f table_builder的查找结果:
Cscope tag: table_builder
   #   line  filename / context / line
   1      1  table_builder.h <<<unknown>>>
   2      1  table_builder.cc <<<unknown>>>

快捷键映射

TODO

参考资料

  1. vim(7.2) :help cscope
  2. cscope man page
  3. http://cscope.sourceforge.net/
  4. https://www.cs.oberlin.edu/~kuperman/help/vim/windows.html
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值