前面我们学习了如何使 vim 像 IDE 一样管理项目代码(《 vim的项目管理工具:project插件》),但是 IDE 还有一个非常有用的特性就是能够很方便的找到某个函数或者变量的定义位置(应该是将鼠标移到函数名处 -> 右键 -> 跳到定义处),今天我们使用 vim 的 cscope 插件实现这个功能。
一、下载安装:
关于下载安装,就是一行命令的事,比如 centos :yum install -y cscope
也可以编译安装:
在 http://cscope.sourceforge.net/ 下载源码包,解压,编译安装:
./configure
make
make install
如果你的 vim 版本比较新的话,cscope 已经被内置了。我们可以使用
whereis cscope
来看看现在系统是否内置或已经安装了 cscope。
二、使用 cscope 插件:
1、生成 cscope 数据库:
在使用 cscope 之前,我们必须为代码生成一个 cscope 数据库。
在你的项目根目录下运行下面的命令:
cscope -Rbq
执行完该命令,项目根目录下会生成三个文件:cscope.out、cscope.in.out、cscope.po.out。
其中 cscope.out 就是我们要生成代码索引数据库。而 cscope.in.out 和 cscope.po.out 是使用选项 ”-q“ 生成的,可以加快 cscope 的索引速度(有些系统可能不会生成这两个文件,但是并不会影响 cscope 的功能)
在缺省情况下,cscope在生成数据库后就会进入它自己的查询界面,我们一般不用这个界面,所以使用了”-b“选项。如果你已经进入了这个界面,按CTRL-D退出。
Cscope在生成数据库中,在你的项目目录中未找到的头文件,会自动到/usr/include目录中查找。如果你想阻止它这样做,使用”-k“选项。
而 -R 是递归创建的意思,就是创建包括根目录下的所有子目录文件的索引数据库。
Cscope缺省只解析C文件(.c和.h)、lex文件(.l)和yacc文件(.y),虽然它也可以支持C++以及Java,但它在扫描目录时会跳过C++及Java后缀的文件。如果你希望cscope解析C++或Java文件,需要把这些文件的名字和路径保存在一个名为cscope.files的文件。当cscope发现在当前目录中存在cscope.files时,就会为cscope.files中列出的所有文件生成索引数据库。通常我们使用 find 来生成cscope.files文件。
好,现在我们以之前的项目为例子:/home/www/thinkphp
先进入项目根目录:
cd /home/www/thinkphp
创建索引数据库:
注意,由于该项目不是 C 语言项目,正如前面陈述,我们应该先生成 cscope.files 文件:
find . -type f > cscope.files
现在我们看看到底 cscope.files 文件的内容都有啥:
cat cscope.files
返回如下:
其实就是将 /home/www/thinkphp 目录及其子目录下的所有文件保存下来而已。
现在我们使用
cscope -Rq
即可生成索引数据库。为什么没有使用 -R 参数递归查找子目录?因为在 cscope.files 文件中已经包含了子目录中的文件。
**注意:**find命令输出的文件以相对路径表示,所以cscope.out的索引也相对于当前路径。如果你要在其它路径中使用当前的cscope.out,需要使用下面介绍的“-P”选项。
Cscope只在第一次解析时扫描全部文件,以后再调用cscope,它只扫描那些改动过的文件,这大大提高了cscope生成索引的速度。
下表中列出了cscope的常用选项:
- R: 在生成索引文件时,搜索子目录树中的代码
- b: 只生成索引文件,不进入cscope的界面
- q: 生成cscope.in.out和cscope.po.out文件,加快cscope的索引速度
- k: 在生成索引文件时,不搜索/usr/include目录
- i: 如果保存文件列表的文件名不是cscope.files时,需要加此选项告诉cscope到哪儿去找源文件列表。可以使用”–“,表示由标准输入获得文件列表。
- I dir: 在-I选项指出的目录中查找头文件
- u: 扫描所有文件,重新生成交叉索引文件
- C: 在搜索时忽略大小写
- P path: 在以相对路径表示的文件前加上的path,这样,你不用切换到你数据库文件所在的目录也可以使用它了。
2、实现搜索功能:
首先进入我们的项目:
vim +Project
现在我们输入(cs 是 cscope 的缩写):
:cs add cscope.out
在vim中使用cscope非常简单,首先调用”cscope add“命令添加一个cscope数据库。
添加完数据库后,我们可以查看数据库连接状态:
:cs show
如果显示如上,则证明我们添加数据库成功,接下来我们就可以愉快的进行搜索了。
cscope命令说明:
:cs find s function_name 查找C语言符号,即查找函数名、宏、枚举值等出现的地方
:cs find g function_name 查找函数、宏、枚举等定义的位置,类似ctags所提供的功能
:cs find d function_name 查找本函数调用的函数
:cs find c function_name 查找调用本函数的函数 这个也比较有用处
:cs find t function_name 查找指定的字符串
:cs find e function_name 查找egrep模式,相当于egrep功能,但查找速度快多了
:cs find f file_name 查找并打开文件,类似vim的find功能
:cs find i function_name 查找包含本文件的文件
其中上面的 find 可以直接缩写成 f ,如 :cs find f file_name 可以写成 :cs f f file_name
如上所示,cscope 的功能可以通过它的自命令 “find” 来实现。
:cs find c | d | e | g | f | i | s | t name
- s : 查找 C 代码符号
- g : 查找本定义
- d : 查找本函数调用的函数
- c : 查找调用本函数的函数
- t : 查找本字符串
- e : 查找本 egrep 模式
- f : 查找本文件
- i : 查找包含本文件的文件
好的,说了这么多,我们来试验一下:
现在我们在项目下查找是否存在 Thinkphp.php 文件:
:cs f f ThinkPHP.php
回车之后你会发现直接打开了 ThinkPHP.php 文件,因为在我们的项目下只有一个 ThinkPHP文件,默认就帮你打开了。
想回到刚才我们打开的文件?使用 Ctrl + t 试试。
现在我们来看看有没有 README.md 文件:
:cs f f README.md
回车,如图:
我们可以输入 # 列下面的序号,然后回车,即可打开对应的文件(直接回车不打开文件)。 Ctrl + t 回到之前的文件。
大家还可以试试其他的命令选项,比如我们来看看 index() 函数在哪定义了:
:cs f g index
简单使用 cscope 的功能就差不多了。
三、建议:
在前面我们可以看到,每次进来一个项目都需要先添加索引数据库才能继续使用 cscope 的功能,能不能自动添加呢?答案是可以的!
我在 centos 7 的 /etc/vimrc (centos 7 中的 vim 是自带 cscope 插件的)中发现以下配置:
if has("cscope") && filereadable("/usr/bin/cscope")
set csprg=/usr/bin/cscope
set csto=0
set cst
set nocsverb
" add any database in current directory
if filereadable("cscope.out")
cs add $PWD/cscope.out
" else add database pointed to by environment
elseif $CSCOPE_DB != ""
cs add $CSCOPE_DB
endif
set csverb
endif
大家可以将这段脚本添加到你自己的 vim 配置中(可以添加到 ~/.vimrc,如果是ubuntu 的话可以添加到 /etc/vim/vimrc 中,centos 可以添加到 /etc/vimrc 中)
网上的很多文章还给出了快捷键的配置,但是我并没有添加,因此关于这部分的内容大家还是百度吧。
本篇文章由于参考了太多网上朋友的资源,因此就不在给出链接了。
更多的命令解析大家可以参考这篇文章:《 Cscope的使用(领略Vim + Cscope的强大魅力)》