我可以跳转到多个C ++源文件项目中的函数声明或定义吗?

假设我有一个头文件foo.hpp

int bar();


和源文件foo.cpp

#include "foo.hpp"
int bar() { return 42; }


和主文件main.cpp

#include "foo.hpp"
int main() { bar(); return 0; }


vim可以找到吗来自bar()函数的函数main的定义和声明?

#1 楼

旺盛的ctags是实现此目的的最简单方法。
在GNU / Linux(例如Ubuntu或Debian)下,您应该可以做到。

(对于OSX,“ $ brew install ctags”就足够了;对于Windows,您可能要访问http://ctags.sourceforge.net/并下载独立的可执行文件)。然后导航到项目的根文件夹并运行

sudo apt-get install exuberant-ctags


这将扫描您的整个项目并创建一个./tags文件,vim将自动使用该文件使您能够按一下键跳到功能。即:

ctags -R --exclude=.git .


将光标放在要查看其实现的功能上。
还有其他组合和许多命令模式功能,可让您也可以通过ctags浏览代码(例如,按Ctrl + t跳到旧的标签堆栈条目)。有关概述,请参见:help 29.1

请注意,对于代码中的每个重大更改,您都必须重新运行ctags并使其重新索引项目。您可以手动执行此操作,也可以教Vim通过热键或写入操作执行此操作。

提示:如果您广泛使用ctags,也许vim-taglist(http://vim-taglist.sourceforge.net)插件也值得一看。它为您提供了一个IDE样式的轮廓,并列出了该类/文件的所有功能。

评论


有两件值得了解的事情:通用标签已在许多方面取代了旺盛的标签。另外,如何让git同步您的标签

– D. Ben Knoble♦
19-10-24在11:55

#2 楼

到目前为止,我可以为找到函数的声明或定义的问题命名两个解决方案。我知道还有另一种基于标签的众所周知的解决方案,但是由于我不使用它,所以我会让其他人给您。 :GoToDefinition一对命令。

我使用的一个(很难改变10年的习惯)。我的lh-tags插件提供了一种生成ctags数据库并进行增量更新的方法。并且它还提供了一种方法(:GoToDeclaration)来呈现与光标(/所选择的内容)匹配的所有声明和定义。由于此解决方案依赖于ctags,因此它也无法知道游标下的标识符实际上与哪个重载有关。在此主题上,其他基于ctags的解决方案应该同样(不如(好))。但是,YCM在这里应该更好。开始了clang-indexer的分支和将其封装的相关vim插件。但是随着YCM的到来,我会忘记此解决方案)

编辑:截至2019年,最有效的解决方案依靠LSP服务器。我正在使用COC + ccls进行索引,跳转并做更多事情。当我懒于为一个我不会花太多时间或无法安装最新版本的clang和ccls的项目配置COC时,我会回到基于标签的解决方案。

评论


感谢您的输入,将测试每个解决方案。我测试了YouCompleteMe,只有GoToDeclaration可用于多个源文件。这是来自文档的有关GoToDefinition的引文:对于C系列语言,仅当符号的定义位于当前翻译单元中时,此方法才有效。此外,命令为:YcmCompleter GoTo *。

–长谷川艾伦
15年2月19日在18:03

我错过了这条线。这意味着clang_indexer可能仍然有用。其他解决方案可能很难安装。如有需要,请随时给我发送电子邮件。

–卢克·赫米特(Luc Hermitte)
2015年2月19日在18:16



#3 楼

没有什么选择。第一个是ctags。如果需要更高级的索引器,则cscope是更好的选择。例如,它将允许您列出给定函数的所有调用方。这些工具会在没有真正正确理解代码的情况下为您的代码建立索引(它们确实具有简单的语法定义来了解给定符号的含义)。扩展语法也相对容易。 taglist插件是这些工具所必需的,可以扩展索引器语法以在标记列表中显示结果。它建立在YouCompleteMe的顶部,因此具有适当的解析器。这样就可以检查代码的语法和语义。

然后,如果您使用的是具有领域特定语言或嵌入式代码的代码,则通常只能通过文件来查找。替代方法是llvm perl脚本,它试图帮助完成此任务。

#4 楼

我认为这就是您所需要的。 Vim本身与ctags集成在一起,可以很容易地跳转到函数定义和声明。

评论


请添加链接文章的摘要。当链接失效时,仅链接的答案将变得无用。

–muru
2015年2月20日下午6:32