如何使用Vim跳转到函数定义?例如,在Visual Assist中,我可以在函数下输入Alt+g,它会打开一个上下文菜单,列出带有定义的文件。
如何在vim中做这样的事情?
如何使用Vim跳转到函数定义?例如,在Visual Assist中,我可以在函数下输入Alt+g,它会打开一个上下文菜单,列出带有定义的文件。
如何在vim中做这样的事情?
当前回答
G *在没有设置标签的情况下做得不错。
也就是说,输入g,*(或者只输入* -请参见下文)来搜索光标下的单词(在本例中是函数名)。然后按n转到下一个(或Shift-n为前一个)事件。
它不会直接跳转到定义,因为这个命令只是在光标下搜索单词,但是如果您现在不想处理设置ctags的问题,那么至少可以避免重新键入函数名来搜索它的定义。
——编辑 虽然我已经使用g*很长时间了,但我最近发现了这些快捷键的两个快捷键!
(a) *将跳转到光标下出现单词的下一个位置。(不需要输入g,在vi中输入'goto'命令)。
(b) #以类似的方式指向前一个事件。
N和N仍然可以工作,但是'#'通常非常有用,可以从相反的方向开始搜索,例如,在游标下查找变量的声明。
其他回答
保罗的第二个回答是:是的,ctags(尤其是exuberant-ctags (http://ctags.sourceforge.net/))很棒。我还添加了这个到我的vimrc,所以我可以为整个项目使用一个标签文件:
set tags=tags;/
正如Paul Tomblin提到的,你必须使用标签。 您还可以考虑使用插件来选择合适的一个或在游标下预览函数的定义。 如果没有插件,你将会头疼地试图从数百个重载的“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
如果所有内容都包含在一个文件中,则有命令gd(就像在'goto definition'中一样),它将带您到光标下的文件中单词的第一个出现处,这通常是定义。
在生成ctags之后,你还可以在vim中使用以下命令:
:tag <f_name>
以上将带您了解函数定义。
TL; diana:
您可以使用内部VIM功能来实现这一点,但现代的(更简单的)方法是使用COC来完成类似智能的补全,使用一个或多个语言服务器(LS)来实现跳转到定义(以及更多)。为了获得更多的功能(但跳到定义并不需要),您可以安装一个或多个调试器,从而获得完整的IDE体验。
其次是使用原生VIM的定义-搜索功能,但它是为C预处理器的#define指令发明的,对于大多数其他语言需要额外的配置,对于一些根本不可能(你也错过了其他IDE特性)。最后,还有一种退路就是标签。
快速启动:
install vim-plug to manage your VIM plug-ins add COC and (optionally) Vimspector at the top of ~/.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' call :source $MYVIMRC | PlugInstall to reload VIM config and download plug-ins restart vim and call :CocInstall coc-marketplace to get easy access to COC extensions call :CocList marketplace and search for language servers, e.g.:
输入python找到coc-jedi, 输入PHP查找coc-phpls,等等。
(可选)参见:h VimspectorInstall安装额外的调试器,例如:
: VimspectorInstall debugpy, :VimspectorInstall vcode -php-debug等
完整的故事:
语言服务器(LS)是一个独立的应用程序(每一种编程语言都有一个),它在后台运行,实时分析整个项目,将额外的功能暴露给编辑器(任何编辑器,不仅仅是vim)。你会得到这样的东西:
名称空间感知标记补全 跳转到定义 跳转到下一个/上一个错误 查找对一个对象的所有引用 查找所有接口实现 在整个项目中重命名 悬停文档 代码片段,代码动作,格式化,检测和更多…
与语言服务器的通信通过语言服务器协议(LSP)进行。nvim和vim8(或更高版本)都通过插件支持LSP,最流行的是完成征服(COC)。
Lang Server网站上有正在开发的语言服务器及其功能列表。并非所有这些都是由COC扩展提供的。如果你想使用其中之一,你可以自己编写一个COC扩展,或者手动安装LS,并使用以下VIM插件的组合作为COC的替代方案:
LanguageClient -处理LSP 在输入时触发完成
与调试器的通信通过调试适配器协议(DAP)进行。VIM最流行的DAP插件是Vimspector。
语言服务器协议(LSP)是由微软为Visual Studio Code创建的,并作为一个开放源码项目发布,具有许可的MIT许可证(通过与Red Hat和Codenvy合作进行标准化)。后来微软也发布了调试适配器协议(DAP)。vcode支持的任何语言在VIM中都是受支持的。
我个人建议使用COC + COC扩展提供的语言服务器+ ALE进行额外检测(但为了避免与COC冲突,LSP支持被禁用)+ Vimspector + Vimspector提供的调试器(称为“gadget”)+以下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跳转到定义:
If you really don't want to use Language Server and still want a somewhat decent jump to definition with native VIM you should get familiar with :ij and :dj which stand for include-jump and definition-jump. These VIM commands let you jump to any file that's included by your project or jump to any defined symbol that's in any of the included files. For that to work, however, VIM has to know how lines that include files or define symbols look like in any given language. You can set it up per language in ~/.vim/ftplugin/$file_type.vim with set include=$regex and set define=$regex patterns as described in :h include-search, although, coming up with those patterns is a bit of an art and sometimes not possible at all, e.g. for languages where symbol definition or file import can span over multiple lines (e.g. Golang). If that's your case the usual fallback is ctags as described in other answers.