之前已经详细的介绍了在 vim中使用ctags ,这篇文章我们就来详细介绍一下如何在vim中使用cscope。
首先,我们还是了解一下什么是cscope。
简单来讲,cscope主要用来协助浏览C/C++语言,他的功能要强大于ctags,不仅支持变量/函数的定义查询,还记录了函数的调用处查询等功能,所以也有说法称cscope的诞生就是为了取代ctags。
无论这个说法是否有据可依,对使用方来说,当然是希望功能越强大方便越好啦,所以这也是我们为什么讲ctags和cscope都装上的原因啦。
第二,我们来说一下vim的支持。
cscope没有ctags那么幸运,cscope在大部分的linux下的vim中是没有提供支持的(但是在windows下的gvim都提供了支持),所以,如果你打算要在linux下面使用vim+cscope,那么1,你要下载安装cscope。2,你要重新编译vim,加上支持选项: --enable-cscope 。
当然,cscope也提供了windows版(否则windows下gvim怎么和cscope搭配嘛...),分别下载地址如下:
cscope(linux):http://cscope.sourceforge.net/
cscope(windows):http://sourceforge.net/projects/mslk/files/
当然,安装的最后一步就是,不要忘记讲cscope放进的环境变量里!
第三,好了,假设你已经搭建好了vim+cscope的环境,那么现在就是我们学习怎么用的时候了
function Do_CsTag()
if(executable("cscope") && has("cscope") )
if(has('win32'))
silent! execute "!dir /b *.c,*.cpp,*.h,*.java,*.cs >> cscope.files"
else
silent! execute "!find . -name "*.h" -o -name "*.c" -o -name "*.cpp" -o -name "*.m" -o -name "*.mm" -o -name "*.java" -o -name "*.py" > cscope.files"
endif
silent! execute "!cscope -b"
if filereadable("cscope.out")
execute "cs add cscope.out"
endif
endif
endf
调用这个函数就可以用cscope生成数据库,并添加到vim中,具体每个命令意义如下:
if(has('win32'))
silent! execute "!dir /b *.c,*.cpp,*.h,*.java,*.cs >> cscope.files"
else
silent! execute "!find . -name "*.h" -o -name "*.c" -o -name "*.cpp" -o -name "*.m" -o -name "*.mm" -o -name "*.java" -o -name "*.py" > cscope.files"
上面的函数,通过操作系统的不同,用不同的命令实现,将当前目录的源码文件导入到一个叫做cscope.files的文件中。这个文件是cscope用来生成数据库时的默认存储文件列表的文件。 不理解dir命令?看看这篇文章吧
http://hi.baidu.com/moodmusic/blog/item/888856ed309605d7b21cb141.html
silent! execute "!cscope -b"
这个命令就是csope在生成数据库,你会发现生成了一个cscope.out的文件,这个就是生成数据库,实际上如果加上参数-q来加快索引速度的话,还会生成cscope.in.out, cscope.po.out这两个文件,各个参数意义如下: -b : 默认情况下,cscope在生成数据库后,会进入cscope自己的界面,我们在vim中使用他,当然不希望有这样的界面,就可以用-b来屏蔽掉。
execute "cs add cscope.out"
最后这一步,就是在vim中添加了cscope.out这个数据库。 下面列出cscope的常用生成数据库选项:
-R: 在生成索引文件时,搜索子目录树中的代码,因为我们已经在cscope.files中把所有的文件都打印入了列表中,所以 -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,这样,你不用切换到你数据库文件所在的目录也可以使用它了。
好了,到了这里,cscope的原理大家应该都清楚了,那么在vim中怎么使用呢? "cscope find"的用法:
cs find c|d|e|f|g|i|s|t name 0 或 s 查找本 C 符号(可以跳过注释) 1 或 g 查找本定义 2 或 d 查找本函数调用的函数 3 或 c 查找调用本函数的函数 4 或 t 查找本字符串 6 或 e 查找本 egrep 模式 7 或 f 查找本文件 8 或 i 查找包含本文件的文件
但是谁也不想敲这么多命令吧,所以我在vimrc中建了这样一个映射:
nmap <C-@>s :cs find s <C-R>=expand("<cword>")<CR><CR>:copen<CR>
nmap <C-@>g :cs find g <C-R>=expand("<cword>")<CR><CR>
nmap <C-@>c :cs find c <C-R>=expand("<cword>")<CR><CR>:copen<CR>
nmap <C-@>t :cs find t <C-R>=expand("<cword>")<CR><CR>:copen<CR>
nmap <C-@>e :cs find e <C-R>=expand("<cword>")<CR><CR>:copen<CR>
nmap <C-@>f :cs find f <C-R>=expand("<cfile>")<CR><CR>:copen<CR>
nmap <C-@>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>:copen<CR>
nmap <C-@>d :cs find d <C-R>=expand("<cword>")<CR><CR>:copen<CR>
实际上就是参考 cscope_maps.vim 这个文件,大家可以去下载他,然后直接放到plugin目录就行。 最后,我们来说一下cscope和ctags的兼容问题。我在vimrc中配置了一段代码:
if has("cscope")
set cscopequickfix=s-,c-,d-,i-,t-,e-
set csto=0
set cst
set csverb
endif
官方解释如下:
http://vimcdoc.sourceforge.net/doc/if_cscop.html
简单来说,主要功能就是同时搜索ctags和cscope的标签,并且cscope优先扫描。
好啦,在vim(gvim)中使用cscope的介绍就到这里啦,有兴趣的朋友可以赶紧试一下啦~~
lyndonjiang on #
有个疑问,您在IDE(2)里的这段代码
if has("cscope")
silent! execute "cs kill -1"
endif
和您这里的代码
if has("cscope")
set cscopequickfix=s-,c-,d-,i-,t-,e-
set csto=0
set cst
set csverb
endif
都是调整cscope和ctags的兼容问题的,两者有什么区别?
Reply
Dante on #
呃,这个不是调整他们俩的兼容性……而是判断vim是否编译时加入了cscope支持……
Reply
lyndonjiang on #
那我是不是应该自己加上调整兼容性那段语句呢?
Reply
Dante on #
汗,我一开始以为你是说
if has(”cscope”)这句,
if has("cscope")
set cscopequickfix=s-,c-,d-,i-,t-,e-
set csto=0
set cst
set csverb
endif
这整个一段确实是调整兼容性的~~~在vimrc里面加上就可以啦
Reply
lyndonjiang on #
博主你好,请问一下,vim有没有什么插件或者其他手段可以实现这个功能:
我拿一个C工程举例,
把一个工程的所有相关头文件和C文件的文件名以及他们的目录这些信息保存成一个文件;这样下次打开这个文件,我们就可以选择打开这个工程的某些文件了,对这个工程的结构也有个很清楚的了解。
有了这个功能再配合ctag,VIM就变得更像IDE了。
Reply
Dante on #
尝试一下project这个插件,应该能满足你的需求。
http://www.vim.org/scripts/script.php?script_id=69
Reply
lyndonjiang on #
博主,谢谢你的提示,在你的提示下我找到了这个插件winwkspaceexplorer,这个更能满足我的要求。
可是我水平有限,目前是Taglist和Workspace这两栏水平并列显示。
本来我是用winmanager把Taglist和netrw(或bufexplorer)上下显示在一栏里,可是用了这个Workspace插件后就不行了。
我的目标是可以把Workspace,Taglist,netrw(bufexplorer)显示在上下一栏里。我尝试了let g:winManagerWindowLayout='Workspace|TagList|FileExplorer,BufExplorer',这句不行。
Reply
lyndonjiang on #
多谢楼主了,上面那个问题我自己搞定了,
因为winwkspaceexplorer这个插件的关键字是WKSpaceExplorer,不是Workspace,所以用这句话就好了nmap wk :WKSpace%
let g:winManagerWindowLayout = 'WKSpaceExplorer|TagsExplorer|FileExplorer|BufExplorer'。
没有用竖直一起显示,那样太浪费空间,用了ctrl+n来切换了,这样看起来舒服。
还在_vimrc里加了这句话nmap wk :WKSpace%
这样我可以直接打开编辑好的.vimwks文件,按wk就能直接生成工程目录了。
嘿嘿,把这些插件和vimrc备份起来去。
Reply
lyndonjiang on #
我爱死这个插件了,现在我的Vim真是比IDE好用多了,但是有个美中不足。就是这个工程被打开后,工程下每个Group(这个插件里是叫filter)是默认完全展开的,这样的话如果大工程的话会很悲剧。
我想要实现默认不展开的话只能修改下插件文件本身了。
我看了一下恐怕可以在下一段代码前加个if语句,但是我不知道怎么加。我把下段代码全部注释了,可以“实现”无论怎么点,该filter都不能被展开。
for lll in sort(keys(s:wksDict[l]['filters'][ll]['files']))
let l:temp = s:spacesString[0:l:spaces].lll
put=l:temp
endfor
博主有空的话指导我一下吧,谢谢!
Reply
Dante on #
这个插件我之前还真没用过……我研究一下哦,等有消息就给你留言~~
Reply
lyndonjiang on #
好,反正这一页现在是我的浏览器首页
Reply
Dante on #
受宠若惊,受宠若惊啊……,哈哈,放心哦,我给你留言你会收到邮件的~~
Reply
grassofhust on #
那段代码我感觉是加空格缩进的
关闭的话应该是fold
set fdm=indent
还没有看那个插件,只是根据描述猜测的。
Reply
lyndonjiang on #
"Lets display all the files under the filter
for lll in sort(keys(s:wksDict[l]['filters'][ll]['files']))
let l:temp =s:spacesString[0:l:spaces].lll
put=l:temp
endfor
那你应该是猜错了:)这段代码上面有注释的。
Reply
pwangeng on #
function Do_CsTag()
这个函数如何使用? 在vim内用:function Do_CsTag()没有作用
Reply
vimBenginer on #
太棒了,真没想到能用dir生成cscope.files
Reply
依云 on #
我一般是用 find 来生成的 :-P
Reply
Dante on #
find是windows原生的命令吗?装了个mingw,结果都知道是谁的命令了。。。
Reply
依云 on #
不是。不过这里 http://unxutils.sourceforge.net/ 有Windows版的。
Reply
可可火山 on #
今天想用cscope for windows,找怎么生成list文件,又找到这里来了。
dir帮助瞄了遍,就发现已经google出结果了~ nice
Reply
Dante on #
呵呵,cscope确实不错,就是基于他的插件有点少~~
Reply
可可火山 on #
C:\workspace\jdk6source>cscope -Rbkq -i cscope.files
cscope: -q option mismatch between command line and old symbol database
Input file specified two times.
cscope: cannot create inverted index; ignoring -q option
cscope: removed files ncscope.in.out and ncscope.po.out
奇怪,-q参数不支持还是啥的,没有生成index,工作的超慢,我jdk6的cscope.out有70M左右,find一下要卡一会儿,好像哪里有瞄到windows版-q参数的问题,现在找不着了,额~
Reply
Dante on #
呃,没尝试用他来生成java的呢,我在windows版本下加上-q的时候也会报错,据说会加快索引速度
Reply
ssddn on #
出错是由于它找不到对应的sort命令(windows带的sort.exe不行,得用GNU的sort)导致的,如果在cygwin环境下执行这个命令就应该没有问题了。
Reply
Dante on #
原来如此,多谢指教~~~~
Reply
是否应该要修改一下 on #
你好,首先非常感谢你的博文,的确让我获益非浅呀,但是我发现:
silent! execute "!dir /b *.c,*.cpp,*.h,*.java,*.cs >> cscope.files"
这句是否应该将“>>”改为“>”,因为如果我在一个目录下多次生成数据库时,cscope.files里面的内容会多次复制,最后导致find出来的数据也是多次重复的。
Reply
Dante on #
呵呵,多谢多谢,确实该改一下~
Reply
ssddn on #
用dir只能生成当前目录的文件列表,使用for命令可以像Linux下的find一样遍历目录树。
请将下面两行命令copy到bat文件中,并执行,如想在命令行上直接执行,请将命令中两处%%a改为%a。
del cscope.files
for /r . %%a in (*.c,*.cpp,*.h,*.hpp) do echo %%a >> cscope.files
Reply
Dante on #
这样啊~对windows下的命令不熟,呵呵~~多谢~~
Reply
吴叔 on #
弱弱的问一下nmap s :cs find s =expand(""):copen这个里面的@什么键?谢谢博主
Reply
Dante on #
呃,@就是键盘左上的2。。。。
Reply
iroger on #
我很想用这个,但不知道好不好用,你给建意一下吧! 呵呵!
Reply
奥西里斯 on #
博主你好……我现在用的cscope,查找到结果却无法跳转……
如果在命令行里面输入的话就会提示
处理 BufEnter 自动命令 "*" 时发生错误:
E344: cdpath 中找不到目录 "funcs"
E472: 命令执行失败
感觉上应该是当前目录不是根目录,而cscope却是从当前目录进行跳转的,这个要怎么处理呢
Reply
小杨 on #
在源代码根目录上执行Do_CsTag(),
根目录下有很多目录, 生成的cscope.files包含所有目录的文件, 但在子目录里查找函数定义时, 会出现
E429: File 'agent/xxx.cpp" does not exist, 怎么办吖?
Reply
Dante on #
:set tags,看一下加载的tags路径是否正确
Reply
小杨 on #
直接在子目录再生成一次Do_CsTag()就行了,
cscope + ctag, 生成后自动补全插件omnicomplete下打左括号时会打开相应的文件(preview), set completeopt=menu时仍无效, 且光标会跳到taglist的函数列表那....引结吖
Reply
jwkljh on #
if has("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
endif
我想根据项目或代码的路径选择对应的cscope.out数据库,但是上面的脚本好像不起作用,我用的windows下的gvim,跪求大师指导。
Reply
月下幽杳 on #
问下用vim调用java编译器,怎么把编译错误信息收集到quickfix窗口
Reply
Dante on #
:help quickfix,是有办法的,文档的实例代码里就有java的。
Reply
HelloKitty on #
请问楼主你最下面介绍的快捷键映射分别代表哪几个快捷键啊?
Reply
火冷 on #
按说明修改了_vimrc文件,现在打开空白的gvim,也会先闪下cmd窗口生成cscope.files,怎么增加格式判断?
Reply