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


15

我可以跳转到多个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函数中找到函数的定义和声明吗?

Answers:


15

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

sudo apt-get install exuberant-ctags

(对于OSX,“ $ brew install ctags”就足够了;对于Windows,您可能要访问http://ctags.sourceforge.net/并下载独立的可执行文件)

然后导航到项目的根文件夹并运行

ctags -R --exclude=.git .

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

Ctrl + ]

将光标放在要查看其实现的函数上。还有其他组合和许多命令模式功能,这些功能也使您也可以使用ctags浏览代码(例如,Ctrl+ t跳转到较早的标签栈条目)。请参阅:help 29.1以获取概述。

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

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


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

4

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

首先比较时髦:YouCompleteMe有一个:GoToDefinition和一:GoToDeclaration对命令。

我使用的一种(很难改变10年的长期习惯)。我的lh-tags插件提供了一种生成ctags数据库并进行增量更新的方法。并且它还提供了一种方法(CTRL+W Meta+Down),用于显示与光标(/所选择的内容)匹配的所有声明和定义。由于此解决方案依赖于ctags,因此它也无法知道游标下的标识符实际上与哪个重载相关。在此主题上,其他基于ctags的解决方案应该同样(不如(好))。但是,YCM在这里应该更好。

讨论:我确实将lh-tags实施为更符合人体工程学的替代方案:tselect

(实际上,我记得第三个解决方案:我已经启动了clang-indexer的分支以及将其封装的相关vim插件。但是随着YCM的到来,我会忘记这个解决方案)

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


1
感谢您的输入,将测试每个解决方案。我测试了YouCompleteMe,并且仅GoToDeclaration适用于多个源文件。这里有大约从文档报价GoToDefinitionFor C-family languages this only works ... when the definition of the symbol is in the current translation unit.。另外,命令为:YcmCompleter GoTo*
长谷川艾伦2015年

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

3

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

如果您除了索引器之外还需要其他东西,YouCompleteMe则可能需要语法检查。它建立在之上,llvm因此具有适当的解析器。这样可以检查代码的语法和语义

然后,如果您使用具有特定于域的语言或嵌入式代码的代码,则通常只能通过文件来获取最终结果。替代方案是Ack尝试帮助完成此任务的perl脚本。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.