vi/Vim + Cscope/Ctags

前提:已经安装了vim,建议安装vim-full,即:sudoapg-get install vim-full
   
    1.ctags:

    下载ctags,可从官网上下载,如:ctags-5.7.tag.gz

    tarxzvf ctags-5.7.tag.gz

    cdctags-5.7

    ./configure

    make

    sudomake install

    具体操作时目录可能不一样

    2.taglist:

    cd~

    mkdir.vim

    cd.vim

    mkdirplugin

    unzip(path自定)/taglist_45.zip

    ls

    //解压成功会在.vim下生成两个文件夹,doc, plugin

    测试一下插件是否安装好,可以运行一下命令

    1ctags--version,有信息则说明安装好了

    2、进入一个原文件,vitest.c,进入命令模式,输入命令":Tlist",如果出现左右两栏分栏显示,则说明OK

    ctags关联到taglist

    vi~/.vim/plugin/taglist.vim

    在命令行模式下输入命令查抄":/loaded_taglist"

    找到后,在该行前面加上如下行:

    letTlist_Ctags_Cmd="/usr/bin/ctags""目录可能有变,或许是/usr/local/bin/ctags

    OK

    到你想浏览的目录下

    ctags-R

    vitest.c

    :syntaxon //打开语法高亮

    :setcindent //打开自动缩进

    :Tlist//OK

3.cscope

sudo apt-get install cscope


安装好开发工具后,配置一下.vimrc文件在用户的主目录下:

solaris当前用户没有这个文件,需要创建

我的.vimrc如下:

set hlsearch
set ai
syntax on
set number
set nocompatible
set columns=80
filetype on
set history=1000
set autoindent
set smartindent
set tabstop=4
set shiftwidth=4
set showmatch
set guioptions-=T
set vb t_vb=
set ruler
set nohls
set noexpandtab
set ignorecase
set mouse=a
set cindent
set incsearch
set fencs=utf-8,cp936

set showcmd
"Tlist的内部变量。函数列表。
let Tlist_Use_Right_Window=1
let Tlist_File_Fold_Auto_Close=1
" "函数和变量列表
map :TlistToggle
" "全能补全
inoremap
" " 没事,鼠标画线玩的。
noremap :call ToggleSketch()
set wildmenu
" " 启动函数变量快速浏览的时间设置
set updatetime=100
map :split
map :vsplit
map :q!
map :w!
map :wq!

autocmd FileType python set omnifunc=pythoncomplete#Complete


if has("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 cscope.out
                " else add database pointed to by environment
        elseif $CSCOPE_DB != ""
                cs add $CSCOPE_DB
        endif
        set csverb
        set cscopetag
        "set cscopequickfix=s-,g-,d-,t-,e-,f-,i-
endif

摘自:http://blog.csdn.net/Strive_For_You/article/details/6203861


Cscope的主页在http://cscope.sourceforge.net/,如果你的计算机上没有cscope,你可以在此处下载它,在写本文时,它的最新版本是15.6。安装它非常简单,你只需要在cscope的源代码目录中执行下面三条命令:


    ./configure
    make
    make install

1、配置

首先,让vim支持cscope,在~/.vimrc中加入: (root 下)
    set cscopequickfix=s-,c-,d-,i-,t-,e-

    要使用cscope的强大功能,首先需要为你的代码生成一个cscope数据库。生成数据库很简单,在你的项目根目录运行下面的命令:  
     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

这个脚本,首先使用find命令,查找当前目录及子目录中所有后缀名为".h", ".c"和".cc"的文件,并把查找结果重定向到文件cscope.files中。
然后cscope根据cscope.files中的所有文件,生成符号索引文件。

2、使用

在VIM中使用cscope非常简单,首先调用“cscope add”命令添加一个cscope数据库,

cscope add cscope.out /root/sdi

cscope add cscope.out //这个说明在当前目录下有效


然后就可以调用“cscope find”命令进行查找了。VIM支持8种cscope的查询功能,如下:

s: 查找C语言符号,即查找函数名、宏、枚举值等出现的地方
g: 查找函数、宏、枚举等定义的位置,类似ctags所提供的功能
d: 查找本函数调用的函数
c: 查找调用本函数的函数
t: 查找指定的字符串
e: 查找egrep模式,相当于egrep功能,但查找速度快多了
f: 查找并打开文件,类似vim的find功能
i: 查找包含本文件的文件

例如,我们想在VIM 的源代码中查找调用do_cscope()函数的函数,我们可以输入:“:cs find c do_cscope”,回车后发现没有找到匹配的功能,可能并没有函数调用do_cscope()。我们再输入“:cs find s do_cscope”,查找这个C符号出现的位置,现在VIM列出了这个符号出现的所有位置。

http://vimcdoc.sourceforge.net/doc/if_cscop.html#cscope-intro cscope说明文档



拥有了某种工具,往往不等于就能使用好这种工具。拥有工具简单,用好工具、发挥出最大作用则较难。CSCOPE让VIM的使用者有了与SourceInsight"平起平坐“的机会,但是能否将CSCOPE的功能发挥出来还要看你是如何使用它了。

自从VIM”重装上阵“以后,我一直在使用CSCOPE。在使用过程中还是发现了一些”别扭“的事情。一般我会在一个大型Project的源代码的顶层目录使用CSCOPE -Rbq来生成cscope.out文件,如果你在cscope.out所在目录执行VIM的话,VIM会优先将cscope.out作为”符号交叉索引库“(与ctags相比),但是如果你在某个子目录下执行VIM进入编辑状态的话,因当前目录没有cscope.out,所以VIM无法加载cscope.out文件,也就无法在文件间跳转。而必要时你还需要手动执行命令行:cs add {TOP_LEVEL_PATH}/cscope.out才能连接到cscope,发挥其功用。

还有一种情况,如果你有两份基本相同的代码库,其中一份A建立了cscope.out文件(在A的顶层目录使用CSCOPE -Rbq),而另一份B没有建立,当使用B查看代码或编写代码时,手动add A库的cscope.out文件,然后打开B库子目录的一个文件,找到一个符号,用ctrl+]进行跳转,VIM会列出符号列表,当你选择一个时,VIM却提示你“E429: File xx/yy.h does not exist”,原因很简单,就是Cscope以相对路径存储了符号的位置,你从B库的工作目录下当然跳不过去了。

现在我们就要解决这两个问题,我们要做到:
1) 无论在任何目录下执行VIM,VIM都会自动加载当前阶段常用的cscope.out,而无需手动加载;
2) 让cscope.out内的符号以绝对路径的形式存储,这样无论在何处进入VIM,都能跳转到相应的符号定义的文件中;

其实解决上述两个问题的方法有多种,这里只是先说说我的一种方法,估摸着还不是最优的。在cscope官方有篇文章“Using Cscope on large projects”,里面关于cscope.out生成的方法可以解决第二个问题,即使用cscope.files来生成cscope.out。cscope.files中的内容很简单,就是文件列表,将你要进行扫描的所有文件的路径cscope.files中,然后执行cscope -bqk即可得到cscope.out。如果你要解决问题2,那你就将要进行扫描的文件的绝对路径名加入到csccope.files中。用find命令可以轻松帮你做到这一点。这里将这个工作放到了一个shell脚本中去完成了,脚本具有一定的通用性(我的脚本水平:菜鸟级^_^):
/* gen_cscope_files.sh */
#! /bin/bash

TARGET='/export/home1/username/cscope_db/cscope.files'
gen_cscope_files_usage() {
        echo "gen_cscope_files.sh 源码顶层目录(绝对路径) 待扫描子目录1 [待扫描子目录2] ... [待扫描子目录N]"
}

if [ -z ${1} ]; then
        echo "请输入起始目录!"
        gen_cscope_files_usage
        exit 1
fi

if [ ${1:0:1} != '/' ]; then
        echo "请输入起始目录的绝对路径形式!"
        gen_cscope_files_usage
        exit 1
fi

if [ ${#} -lt 2 ]; then
        echo "请输入你要扫描的子目录列表!"
        gen_cscope_files_usage
        exit 1
fi

if [ -s ${TARGET} ]; then
        cat /dev/null > ${TARGET}
fi

for dir in $@
do
        if [ ${dir} != ${1} ]; then
                find ${1}/${dir} \
                -name "*.[hc]" \
                -print >> ${TARGET}
        fi
done
这样你只要选择好你的cscope.files的存放位置(在上面的脚本中是写死的,当然你也可以修改脚本,通过命令行参数传入cscope.files的存放位置),给gen_cscope_files.sh一个源码的顶层目录(绝对路径),再给出你要扫描的子目录列表即可,比如:gen_cscope_files.sh /export/home/username/proj/foo  include src

以上解决了问题2,那问题1呢?我们在.vimrc中做文章。以下代码保证了每次vim被执行后都会将上面生成的cscope.out加载。
if has("cscope")
        if filereadable("/export/home1/username/cscope_db/cscope.out")
                cscope add  /export/home1/username/cscope_db/cscope.out
        endif
endif

到目前为止,你在B库中在任意目录下打开的文件都可以找到相应符号的位置。

你可能感兴趣的:(vi/Vim + Cscope/Ctags)