我主要使用 vim / gvim 作为编辑器,并且正在考虑使用lxr(Linux 交叉参考)和cscope或ctags的组合来探索内核源代码。但是,我从未使用过cscope或ctags,我想听听考虑到我将 vim 用作主要编辑器,为什么会选择其中一个而不是另一个。
4 回答
ctags 启用了两个功能:允许您从函数调用跳转到它们的定义,以及全方位完成。第一个意味着当您结束对方法的调用时,点击g]
或CTRL-]
将跳转到定义或实现该方法的地方。第二个功能意味着当您键入foo.
orfoo->
时,如果 foo 是一个结构,那么将显示一个带有字段完成的弹出菜单。
cscope 也有第一个特性——使用set cscopetag
——但不是最后一个。然而,cscope 还增加了跳转到任何调用函数的地方的能力。
因此,就在代码库中跳转而言,ctags 只会将您带到实现函数的地方,而 cscope 也可以显示调用函数的位置。
为什么你会选择一个而不是另一个?嗯,我两个都用。ctags 更容易设置,运行速度更快,如果你只关心一种跳跃方式,它会显示更少的行。您可以运行:!ctags -R .
并且g]
可以正常工作。它还可以实现全方位的完整事物。
Cscope 非常适合更大、未知的代码库。设置很痛苦,因为 cscope 需要一个包含要解析的文件名列表的文件。同样在 vim 中,默认情况下没有设置键绑定 - 您需要:cscope blah blah
手动运行。
为了解决第一个问题,我有一个cscope_gen.sh
如下所示的 bash 脚本:
#!/bin/sh
find . -name '*.py' \
-o -name '*.java' \
-o -iname '*.[CH]' \
-o -name '*.cpp' \
-o -name '*.cc' \
-o -name '*.hpp' \
> cscope.files
# -b: just build
# -q: create inverted index
cscope -b -q
这将搜索我感兴趣的代码,创建 cscope.files 列表并创建数据库。这样我就可以运行 ":!cscope_gen.sh" 而不必记住所有的设置步骤。
我使用此代码段将 cscope 搜索映射到 ctrl-space x 2,这减轻了 cscope 的另一个不利因素:
nmap <C-@><C-@> :cs find s <C-R>=expand("<cword>")<CR><CR>
有这个 cscope_maps.vim 插件,它设置了一堆类似的绑定。我永远记不起所有选项的含义,所以倾向于坚持使用 ctrl-space。
所以总结一下:ctags 更容易设置并且大部分工作而无需做太多其他事情,它对于全能也很重要。如果您必须维护大型且大部分未知的代码库,cscope 会提供更多功能,但需要更多的工作。
几个月前我也有同样的情况...
ctags 缺乏精确性是一个痛苦。我发现 cscope 对于所有与宏相关的东西都要好得多(并且在 linux 内核中有一堆宏)。
关于用法,这实际上很简单...您只需在内核的根目录下键入 cscope -R ,然后您就不用担心了..(我的意思是,如果您只想探索那是完美的...)
那么,按键绑定都是基于Ctrl-\(对Ctrl过敏的可以重新映射),主要用s和g....,
为内核开发,我不需要这么多的完成......
无论如何,选择cscope,这更方便,更准确。
嗯...您可能应该使用 etags 而不是 ctags...
如果你使用cscope,那么你可以看到调用链,即谁调用了这个函数&这个函数调用了哪些函数?
我不确定这是否可以使用 etags / ctags 来完成......
这只是一个功能......如何找出包含特定函数定义的文件?这只能在 cscope 中获得。
我同时使用cscope 和 etags,它们都适用于不同的事物,尤其是在使用大型代码库(例如 Linux 内核)时。事实上,当我开始使用 Linux Kernel / Xen 时,我就开始使用 cscope 和 etags。
LXR 不是很好,因为您必须单击、通过网络等,而您可以在内核代码上构建 cscope 和标签数据库,而不必通过网络(与 lxr 不同)。
建议使用全局 gtags。可以使用 vim 插件gen_tags将 gtags 与 vim 集成。