Assume I am using some plugin function e.g. For vim-plug, I put this code in my .vimrc at the end

call plug#end()

How to find out where is this function plug#end() is located? from vimrc directly itself

Currently I do following

$ cd ~/.vim/plugged
$ grep -nrs 'somefunction' .

Doing this every time is cumbersome. Is there any clean way to know that function location?

3 Answers 3


There are several approaches:

Open the file

As others have explained, unless the author doesn't follow conventions, the function scope1#scope2#...#scopen#funcname() is supposed to be defined in {rtp}/autoload/scope1/scope2/.../scopen.vim file.

Where {rtp} designates any directory in 'runtimepath' list option. This option is usually automatically handled by plugin managers.

I've been using a very old plugin of mine to open any file anywhere in {rtp}

:SearchInRuntime sp autoload/plug.vim

would split open (:sp) the first file named autoload/plug.vim in the runtime path. Command-line completion is supported.

This approach only work with autoloaded function.

Jump to the function (tags)

This previous approach permits to open the file, but we still have to jump to the function definition. In my workflow, I automatically generate tags for everything under ~/.vim.

Vim offers several commands to navigate around, but tags generation is still up to us. There exist many approaches and plugins. I'm using here another plugin of mine for tag generation, and tag navigation.

What is interesting in lh-tags, given the need to jump to a function, is :LHTags command. As :tag it can take the symbol searched as parameter, but it also supports a kind of fuzzy matching search while :tag needs us to be explicit

:tag plug#end  " explicit
:LHTags pl en  " "fuzzy"

This approach will be tricky with script local functions that exists in several files. :LHTags will display all overloads.

Anonymous functions can't be found this way.

Ask vim what it knows about the function

:verbose function funcname

will return were a function is defined, and its definition.

This will work with every kind of functions:

  • for script local function, the ScriptNumbeR is required
  • even anonymous functions are supported, as long as their object hasn't been garbage-collected.

Jump to an error

Sometimes we want to jump to a function that appears in an error message. In my root library-plugin, I provide a function that decodes the last error message(s) and fills the quickfix-window with the backtrace of the error. The function is not packaged into a command in my plugin, but it's quite simple to do:

" .vimrc
" Parameter: number of errors to decode, default: "1"
command! -nargs=? WTF call lh#exception#say_what(<q-args>)

This will work with every kind of function, even anonymous functions that haven't been GC'ed with their owner object.

  • When using verbose function you'll want to be using it thusly: :verbose function /FunctionName .. the key being the / which will search for functions matching the regex pattern. Otherwise you will often get no results. Dec 21, 2020 at 11:23
  • @Orwellophile. Thanks, I missed this usage of :verbose function. Also, I was answering with the expectation we know the exact function name, either because we see it written before our eyes, or from an error message. In error message cases, I must confess I do not hesitate a single moment to click-select with the mouse and paste a function name in the command line with a middle-click. Hence I've never have a need for the extra /. Dec 21, 2020 at 11:37

With tpope’s scriptease, you can do :Vedit autoload/plug.vim (with completion) to get to the file, but you still have to know that plug# signifies a function in the plug « namespace » of the autoload system.

(Note: not all plugin authors respect this. Some create functions foo#bar in plugin/foo.vim, which is seriously misleading! The function is neither autoloaded nor located in the autoload directory, but rather masquerades as something that it’s not. If you’re reading this, please only put # in autoload! /endrant)


This is a :h autoload function, it's name is a hint on where it's defined.

plug is the name of this script (without .vim), it's parent directory is some_runtimepath/autoload . You already know it's vim-plug, so goto ~/.vim/plugged/autoload, you should see plug.vim there.

You can also use directory with autoload, for example : a#b#c#d#foo#bar is a function defined at some_runtimepath/autoload/a/b/c/d/foo.vim.

If you have trouble find out where the some_runtimepath is, use this command:

:verbose function plug#end
   function plug#end()
        Last set from /usr/local/source/.vim/autoload/plug.vim line 247

If you have create tags for your .vim, you can place cursor at plug#end and use c-] to jump to it's definition directly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.