如何使用Vim跳转到函数定义?例如,使用Visual Assist,我可以在函数下键入Alt+g,它会打开一个上下文菜单,列出带有定义的文件。
如何在vim中做这样的事情?
使用ctags。生成一个标记文件,并使用:tags命令告诉vim它的位置。然后你可以使用Ctrl-]跳转到函数定义
在这个问题中有更多的标签技巧和提示。
你也可以使用cscope和它的'find global symbol'函数。但是你的vim必须用+cscope支持编译,这不是默认的一个构建选项。
如果您知道该函数在当前文件中定义,则可以在正常模式下使用'gD'键击跳转到光标下的符号定义。
第二个Paul的回答是:是的,ctags(尤其是exuberant-ctags (http://ctags.sourceforge.net/))很棒。我还添加了这个到我的vimrc,所以我可以为整个项目使用一个标签文件:
set tags=tags;/
如果所有内容都包含在一个文件中,则有gd命令(如在'goto definition'中),它将带您到光标下的文件中单词的第一个出现处,这通常是定义。
gd
另一种常用的技术是将函数名放在第一列中。这样就可以通过简单的搜索找到定义。
int main(int argc, char *argv[]) { ... }
上面的函数可以在文件中的/^main中找到,或者在目录中的:grep -r '^main' *.c中找到。只要代码被正确缩进,标识符只会出现在一行的开头是在函数定义处。
/^main
:grep -r '^main' *.c
当然,如果你从现在开始不使用ctags,你应该为自己感到羞愧!然而,我发现这个编码标准也是一个有用的补充。
g *在没有设置ctags的情况下做得不错。
也就是说,输入g,*(或者只是* -见下文)来搜索光标下的单词(在本例中,是函数名)。然后按n转到下一个(或转变-n前一个)事件。
它不会直接跳转到定义,因为这个命令只是在光标下搜索单词,但是如果您现在不想处理设置ctags的问题,那么至少可以避免重新键入函数名来搜索它的定义。
(a) *将跳转到光标下一个单词出现的位置。(不需要键入g,即vi中的'goto'命令)。
g
(b) #以类似的方式指向前一个事件。
N和N仍然可以工作,但是'#'通常非常有用,可以从相反的方向开始搜索,例如,在游标下查找变量的声明。
安装cscope。它的工作原理很像ctags,但更强大。要转到定义,执行Ctrl + \ + g而不是Ctrl + ]。当然,您可以同时使用两者。但是对于一个大项目(比如Linux内核),cscope遥遥领先。
cscope
ctags
1- install exuberant ctags。如果你正在使用osx,这篇文章展示了一个小技巧: http://www.runtime-era.com/2012/05/exuberant-ctags-in-osx-107.html < / p >
2-如果你只想在你的目录中包含文件的ctags,在你的目录中运行这个命令:
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)
ctrl + ]
ctrl+o
使用gd或gD将光标放在程序中的任何变量上。
gD
更多的导航选项可以在在这里中找到。
使用cscope来交叉引用大型项目,例如linux内核。
TL;博士:
你可以使用内部的VIM功能来完成这一点,但是一个现代的(更简单的)方法是使用COC来完成类似智能的补全,使用一个或多个语言的服务器 (LS)来跳转到定义(以及更多)。对于更多的功能(但对于跳转到定义不需要),你可以安装一个或多个调试器,并获得完整的IDE体验。
最好的第二种方法是使用本地VIM的名为define-search的功能,但它是为C预处理器的#define指令而发明的,对于大多数其他语言来说需要额外的配置,对于一些根本不可能(你也错过了其他IDE功能)。最后,一个回退方法是ctags。
define-search
#define
快速启动:
~/.vimrc
call plug#begin() Plug 'neoclide/coc.nvim', {'branch': 'release'} Plug 'puremourning/vimspector' call plug#end() " key mappings example nmap <silent> gd <Plug>(coc-definition) nmap <silent> gD <Plug>(coc-implementation) nmap <silent> gr <Plug>(coc-references) " there's way more, see `:help coc-key-mappings@en'
:source $MYVIMRC | PlugInstall
vim
:CocInstall coc-marketplace
:CocList marketplace
python
coc-jedi
php
coc-phpls
:h VimspectorInstall
:VimspectorInstall debugpy
:VimspectorInstall vscode-php-debug
完整的故事:
语言的服务器 (LS)是一个单独的独立应用程序(每一种编程语言都有一个),它在后台运行,实时分析你的整个项目,将额外的功能暴露给你的编辑器(任何编辑器,不仅仅是vim)。你会得到这样的东西:
与语言服务器的通信通过语言服务器协议 (LSP)进行。nvim和vim8(或更高)都通过插件支持LSP,最流行的是完成的征服 (COC)。
nvim
vim8
正在开发的语言服务器及其功能的列表可在朗服务器网站上找到。并非所有这些都是由COC扩展提供的。如果你想使用其中之一,你可以自己编写一个COC扩展,或者手动安装LS,并使用以下VIM插件的组合作为COC的替代方案:
与调试器的通信通过调试适配器协议 (DAP)进行。VIM最流行的DAP插件是Vimspector。
语言服务器协议 (LSP)是由微软为Visual Studio Code创建的,并作为具有许可MIT许可的开源项目发布(由与Red Hat和Codenvy合作标准化)。后来微软也发布了调试适配器协议 (DAP)。vcode支持的任何语言在VIM中都是受支持的。
我个人建议使用COC扩展提供的COC +语言服务器+ 啤酒进行额外检测(但为了避免与COC冲突,LSP支持被禁用)+ 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()
你可以谷歌每个,看看他们做什么。
本地VIM跳转到定义:
如果你真的不想使用Language Server,并且仍然想要在某种程度上体面地跳转到原生VIM的定义,你应该熟悉:ij和:dj,它们代表include-jump和definition-jump。这些VIM命令允许您跳转到项目包含的任何文件,或跳转到包含的任何文件中定义的任何符号。但是,要实现这一点,VIM必须知道包含文件或定义符号的行在任何给定语言中的样子。你可以在~/.vim/ftplugin/$file_type.vim中为每种语言设置set include=$regex和set define=$regex模式,如:h include-search中所述,尽管,提出这些模式有点像艺术,有时根本不可能,例如对于符号定义或文件导入可以跨越多行(例如Golang)的语言。如果这是你的情况,通常的备用方案是ctags,如其他答案所述。
:ij
:dj
include-jump
definition-jump
~/.vim/ftplugin/$file_type.vim
set include=$regex
set define=$regex
:h include-search
在生成ctags之后,你还可以在vim中使用以下命令:
:tag <f_name>
以上将带您了解函数定义。