Vim:如何跳转到声明(类、方法、函数、变量等)?

35

现在我正在处理一个使用了许多类、方法、函数、变量等的文件。是否可能跳转到所有这些声明的位置?请注意,其中一些声明在同一文件中,但其他声明在其他文件中(这些文件可能没有被打开,您不知道声明在哪里,但它们确实存在)。如果声明在目录上一级会发生什么?如果在下一级呢?

不同编程语言的查找声明过程是否相同?还是根据编程语言的不同有不同的解决方法?

据我所读,似乎该解决方案与标签有关。然而,我想知道如何实现这一点(逐步操作),特别是考虑到我们有时需要在其他文件中定义。

我知道可以用IDE完成这个任务,但我想知道通过vim可以实现多大程度的不同。

我只安装了一个新的Vim。我还没有安装任何插件,但愿意安装如果必要的话。也许可以无插件或带插件完成此操作。

提前感谢!


是的,在Vim中,最好使用标签来完成这项工作。您是否阅读了内置文档(:help tags),并且您究竟遇到了什么问题?! - Ingo Karkat
@IngoKarkat:感谢您的评论。我已经阅读了它,但我仍在苦苦挣扎,因为在查找声明时可能涉及不同的文件。此外,对于我来说,是否根据编程语言以不同方式完成所有这些工作还不清楚。 - pablofiumara
3个回答

31

设置标签并不难,但(正如Vim中的大多数事情一样)与IDE相比,它不够自动化。

  1. 首先,您需要使用ctags工具。2022年最常见的是Universal Ctags;2013年则使用的是名为Exuberant Ctags的工具,在ctags.sourceforge.net上找到。
  2. 接下来,您需要为项目中的所有文件创建一个标签数据库(一个名为tags的文件)。通常可以通过从项目根目录运行ctags -R .(也可以在Vim中通过:!ctags ...运行)来完成此操作。 Exuberant Ctags支持41种语言,甚至可以通过正则表达式进行扩展。
  3. 最后,需要配置Vim以获取标签数据库。使用:set tags=./tags;,它将向上搜索文件目录直到根目录。如果有某些全局包含目录,则可以添加这些目录。
  4. 有了这个,您就可以开始使用Vim的标签功能,例如<C-]>:tag

您需要定期更新标签数据库;有一些插件(例如easytags.vim;2022警告:未维护,但仍然可以使用)可以自动为您完成此操作。


3
传递 --exclude=file.js 参数,或者忽略这个警告。 - Ingo Karkat
2
使用 ctags -R 命令,数据库将会在当前(项目根目录)目录中创建,因此所有文件都将是向下的;从文件的角度来看,这是相反的,所以不用担心。 - Ingo Karkat
3
B) 阅读:help 'tags':help file-searching(不要被吓到了!)。 C) 是的,例如。 - Ingo Karkat
2
这个问题要求声明。Ctrl+] 可以带你到定义,但不是声明。我加入了一个项目,使用文档存在于带有声明的 *.h 文件中的注释中,而不是在带有定义的 *.c 文件中。有一种方法可以跳转到声明和定义,这将非常方便。 - bobpaul
2
好的,我明白了。我需要使用ctags的--LANG-kinds=选项来添加函数原型。然后,vim的:tselect命令可以轻松跳转到原型或定义。 - bobpaul
显示剩余5条评论

9
你可以尝试使用gd,它可以跳转到本地定义。如果想要更强大的“跳转到定义”功能,建议你尝试使用Ingo提出的tags

1
我使用you complete me (ycm) plugin,这是一个快速的、随打随现的模糊搜索代码完成引擎,适用于Vim。它支持多种语言,并且非常强大。查看this section以了解如何在您的系统上安装它。
例如,在使用Java Maven项目时,从包含您的pom.xml文件的文件夹中打开所需的文件,插件会扫描所有文件和依赖项。
对于方便使用您请求的功能,我在~/.vimrc中有以下关键映射:
let g:ycm_key_list_select_completion = ['<C-n>', '<Down>']
let g:ycm_key_list_previous_completion = ['<C-p>', '<Up>']
let g:SuperTabDefaultCompletionType = '<C-n>'
nnoremap <leader>jd :YcmCompleter GoToDefinitionElseDeclaration<CR>
nnoremap <leader>ji :YcmCompleter GoToImplementation<CR>
nnoremap <leader>jr :YcmCompleter GoToReferences<CR>

假设您的<leader>映射为,,并且像我一样使用let mapleader = ",",则以下命令有效:
  • ,jd 转到定义或声明
  • ,ji 转到实现
  • ,jr 转到引用
  • Ctrl+n/Ctrl+p 在自动完成弹出的列表中向下/向上移动

不错!然而,Vim已经有了gd用于获取定义,你可以在不使用ycm的情况下使用它。 - charlchad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接