跳转到vim中的函数定义


241

如何使用vim跳转到函数定义?例如,使用Visual Assist,我可以在一个函数下键入Alt+ g,它会打开一个上下文菜单,列出带有定义的文件。

我该如何在vim中做这样的事情?


2
gnu global优于ctags。
吉超

6
@Jichao,您能为我们提供更多有关您的经历的见解吗?gnu global使用哪种语言更适合您?关于您认为我很重要的背景,还有其他事情吗?或者,也许您已经在许多不同的场景中使用了它,并且您似乎/总是喜欢它?您比较喜欢什么?谢谢。
still_dreaming_1 2014年

@Jichao我将您的评论转变为社区Wiki答案。我欢迎您的更改和对此答案的投入。
still_dreaming_1 2014年

Answers:


213

使用ctags。生成一个标签文件,并使用:tags命令告诉vim文件的位置。然后,您可以使用Ctrl- 跳转到函数定义]

这个问题还有更多的标签技巧和窍门。


2
php很像C,因此“旺盛的ctags”应该可以使用它。不知道它是否具有python模式。
Paul Tomblin,2009年

5
没有使用Cscope的经验。什么是
Paul Tomblin,2009年

10
与C的相似性与CTags支持PHP无关。它支持PHP和Python。请查看ctags.sourceforge.net/languages.html以获得完整支持。
数据

1
我如何生成CTAG?
dwaynemac

4
最好参考在哪里学习如何操作这些ctag。
Fzs2

137

如果所有内容都包含在一个文件中,则有一个命令gd(如“ goto definition”中的命令),它将带您进入光标下的单词在文件中的第一个出现,通常是定义。


1
如果光标下没有单词(我宁愿键入),该怎么办?
Fuad Saud 2014年

@FuadSaud只是使用/
LucasB 2014年

6
/几乎总是不精确的,因为它将匹配所有出现的事件。我发现您实际上可以:tag <function_name>通过ctags跳转到定义。
Fuad Saud 2014年

@Faud跳转到定义功能依赖于用光标指向标识符(在每个IDE中)。键入/搜索是另一个功能,您将其混淆。
血腥的

101

g* 在没有设置标签的情况下做得不错。

也就是说,键入g*(或仅*-如下所示)以搜索光标下的单词(在这种情况下为函数名称)。然后按n转到下一个(或Shift- n用于上一个)事件。

鉴于此命令只是在光标下搜索单词,因此它不会直接跳转到定义,但是如果您现在不想处理ctags的设置,则至少可以避免重新设置-键入函数名称以搜索其定义。

-编辑-尽管我已经使用g *很久了,但是最近我发现了这些快捷方式的两个快捷方式!

(a)*将跳到光标下该单词的下一个出现位置。(无需g在vi中键入,'goto'命令)。

(b)#以类似的方式转到上一个事件。

N和n仍然起作用,但是'#'通常对于从反方向开始搜索非常有用,例如,在光标下寻找变量的声明时。


10
*和之间的区别g*是搜索中的单词边界。*进行\<keyword\>搜索(与\bkeyword\b常规正则表达式相同),但g*搜索时keyword不带单词边界。
Nicolai S

如果文件中有一百次函数出现,*那么在找到定义之前,平均要带您50次命中。
naught101 '19

49

在将光标放在程序中的任何变量上时使用gdgD

  1. gd 将带您到当地报关行。
  2. gD 将带您进入全球宣言。

这里可以找到更多的导航选项。

使用cscope交叉引用大型项目​​(例如linux内核)。


14

正如Paul Tomblin所提到的,您必须使用ctags。您也可以考虑使用插件来选择合适的插件或在光标下预览功能的定义。如果没有插件,您会很头疼,因为要选择数百种重载的“ doAction”方法之一,因为内置的ctags支持并不考虑上下文-只是一个名称。

您也可以使用cscope及其“查找全局符号”功能。但是您的vim必须使用+ cscope支持进行编译,这不是默认的构建选项。

如果知道函数是在当前文件中定义的,则可以在常规模式下使用“ gD”击键跳转到光标下的符号定义。

这是下载最多的导航插件
http://www.vim.org/scripts/script.php?script_id=273

这是我写的用于选择上下文,同时跳转到标签http://www.vim.org/scripts/script.php?script_id=2507的代码


嗨,@ mykola-golubyev,您在脚本Detailed description部分提供的链接#2507已损坏。你能再提供一个吗?
FelikZ 2014年

12

另一种常用技术是将函数名称放在第一列中。这样可以通过简单的搜索找到定义。

int
main(int argc, char *argv[])
{
    ...
}

然后可以/^main在文件内部或:grep -r '^main' *.c目录中找到上述功能。只要代码正确缩进,标识符唯一出现在行首的时间就是函数定义。

当然,如果从那时起您还没有使用ctags,那么您应该为自己感到羞耻!但是,我发现此编码标准也是有用的补充。


13
我一直想知道为什么有些编码者会这样写他们的签名!
塔拉许2012年

另外,在编写函数签名时,包括在第一列中的“ {”在内,您可以通过按]]在文件中向前移动和[[向后移动]快速移动到每个函数。
BentChainRing

12

TL; DR:

现代方法是使用COC进行类似智能感知的完成,并使用一个或多个语言服务器(LS)进行跳转到定义(以及更多方式)。要获得更多功能(但跳转定义不需要它),您可以安装一个或多个调试器,以获得完整的IDE体验。快速开始:

  1. 安装vim-plug来管理您的VIM插件
  2. 在以下内容的顶部添加COC和(可选)Vimspector~/.vimrc
    call plug#begin()
    Plug 'neoclide/coc.nvim', {'branch': 'release'}
    Plug 'puremourning/vimspector'
    call plug#end()
    
  3. 调用:source $MYVIMRC | PlugInstall以下载VIM插件
  4. 重新启动vim并致电:CocInstall coc-marketplace以轻松访问COC扩展
  5. 呼叫:CocList marketplace并搜索语言服务器,例如:
    • 输入python要查找的内容coc-jedi
    • 输入php查找内容coc-phpls,等等。
  6. (可选)请参阅install_gadget.py --help以获取可用的调试器,例如:
    • ./install_gadget.py --enable-python
    • ./install_gadget.py --force-enable-php

完整答案:

语言服务器(LS)是一个独立的独立应用程序(每种编程语言一个),它在后台运行并实时分析整个项目,从而为编辑器(不仅是任何编辑器vim)提供了额外的功能。您会得到如下信息:

  • 命名空间感知标签完成
  • 跳到定义
  • 跳到下一个/上一个错误
  • 找到对一个对象的所有引用
  • 查找所有接口实现
  • 在整个项目中重命名
  • 悬停文档
  • 片段,代码操作,格式化,棉绒等等

通过语言服务器协议(LSP)与语言服务器进行通信。双方nvimvim8通过插件(或更高版本)支持LSP,最流行的是完成的征服(COC)。

可以在Lang Server网站上找到积极开发的语言服务器及其功能的列表。并非所有这些都由COC扩展提供。如果要使用其中之一,则可以自己编写一个COC扩展名或手动安装LS,然后使用以下VIM插件的组合来替代COC:

通过调试适配器协议(DAP)与调试器进行通信。用于VIM的最流行的DAP插件是Vimspector

语言服务器协议(LSP)由Microsoft为Visual Studio Code 创建,并以允许的MIT许可证(通过与Red Hat和Codenvy的协作进行标准化)作为开源项目发布。后来,Microsoft也发布了调试适配器协议(DAP)。VIM支持VSCode支持的任何语言。

我个人建议使用COC扩展提供的COC +语言服务器+ ALE进行额外的处理(但禁用LSP支持以避免与COC冲突)+ Vimspector + Vimspector提供的调试器(称为“小工具”)+以下VIM插件:

call plug#begin()
Plug 'neoclide/coc.nvim'
Plug 'dense-analysis/ale'
Plug 'puremourning/vimspector'
Plug 'scrooloose/nerdtree'
Plug 'scrooloose/nerdcommenter'
Plug 'sheerun/vim-polyglot'
Plug 'yggdroot/indentline'
Plug 'tpope/vim-surround'
Plug 'kana/vim-textobj-user'
  \| Plug 'glts/vim-textobj-comment'
Plug 'janko/vim-test'
Plug 'vim-scripts/vcscommand.vim'
Plug 'mhinz/vim-signify'
call plug#end()

您可以在每个Google上搜索以查看其功能。


11

1-安装旺盛的ctags。如果您使用的是osx,则本文将介绍一些技巧:http : //www.runtime-era.com/2012/05/exuberant-ctags-in-osx-107.html

2-如果仅希望仅将文件的ctag包括在目录中,请在目录中运行以下命令:

ctags -R

这将为您创建一个“标签”文件。

3-如果您使用的是Ruby,并且希望为您的宝石添加ctags(这对我使用RubyMotion和我开发的本地宝石真的很有帮助),请执行以下操作:

ctags --exclude=.git --exclude='*.log' -R * `bundle show --paths`

信用:https : //coderwall.com/p/lv1qww (请注意,我省略了-e选项,该选项为emacs而不是vim生成标签)

4-将以下行添加到您的〜/ .vimrc中

set autochdir 
set tags+=./tags;

(为什么使用半冒号:http : //vim.wikia.com/wiki/Single_tags_file_for_a_source_tree

5-转到您想要跟随并点击的单词ctrl + ];如果您想返回,请使用ctrl+o(来源:https : //stackoverflow.com/a/53929/226255


提到的Mac文章的链接已断开。这是更新的链接:runtime-era.blogspot.com/2012/05/… 最好的选择是使用Homebrew
ZaydH


2

安装cscope。它的工作原理非常相似,ctags但功能更强大。要定义而不是Ctrl+ ],请执行Ctrl+ \+ g。当然,您可以同时使用两者。但是对于一个大型项目(例如Linux内核),cscope遥遥领先。


1

生成ctag之后,您还可以在vim中使用以下命令:

:tag <f_name>

以上将带您进行功能定义。

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.