Is there a way to make vim jump to the right matching definition automatically in case of multiple definitions. Our C++ code heavily uses function overloading and vim's handling of ctags does not seems to be ready for it.

For example,

void abc(int a, int b) {


void abc(int a, int b, int c) {


Strangely, ctrl] on


takes to the 1st definition and not the correct definition which is the 2nd. Also, g] prompts for options but that's not what I am looking for.



The documentation (:help ctrl-]) says:

When there are several matching tags for {ident}, jump
to the [count] one.  When no [count] is given the
first one is jumped to.

g] may not be what you are looking for but that's the best you can get in Vim.

Basically, you can't expect ctags and Vim to understand your code, so you'll have to look for a smarter indexer (like cscope, GNU GLOBAL, or something based on clang) or use an actual IDE.


clangd & vim-lsp

I have tested clangd to see whether overloaded functions are actually distinguished when looking for the correct definition from a code line where one of the overloaded functions is used. In my minimal testing configuration using the vim plugin vim-lsp it worked.

Minimal Configuration


source $VIMRUNTIME/defaults.vim
if executable('/usr/local/Cellar/llvm/7.0.0/bin/clangd')
    augroup Clangd
        autocmd User lsp_setup call lsp#register_server({
            \ 'name': 'clangd',
            \ 'cmd': {server_info->['/usr/local/Cellar/llvm/7.0.0/bin/clangd']},
            \ 'whitelist': ['c', 'cpp', 'objc', 'objcpp'],
            \ })
        autocmd FileType c,cpp,objc,objcpp nmap <buffer> gd <plug>(lsp-definition)
        autocmd FileType c,cpp,objc,objcpp setlocal omnifunc=lsp#complete
    augroup END

Installation of vim-lsp which requires async.vim into vim8 packpath

$ cd ~/.vim
$ git clone https://github.com/prabirshrestha/async.vim pack/prabirshrestha/start/async.vim/
$ git clone https://github.com/prabirshrestha/vim-lsp   pack/prabirshrestha/start/vim-lsp/

Now your vim configuration should look like (omitting more deeply nested files and folders)

❯ tree -L 4 -F
├── pack/
│   └── prabirshrestha/
│       └── start/
│           ├── async.vim/
│           └── vim-lsp/
└── vimrc

5 directories, 1 file


Now consider the cpp file

void abc(int a, int b) {


void abc(int a, int b, int c) {


int main(int argc, char const *argv[])
    return 0;

Pressing gd on abc of

  • abc(1,2) jumps to first line, and of
  • abc(1,2,3) jumps to fifth line.

Environment and versions:

  • vim: MacVim 8.1.950 (155); installed from DMG from github on macOS 10.14.3
  • clangd: 7.0.0; installed with $ brew install llvm (not in $PATH by default, use absolute path)
  • vim-lsp: e3f6933 (Mar 7, 2019) and async.vim: f301455 (Feb 13, 2019)

As romanl stated, ctags doesn't really understand the code, so the best it can do is point you to functions sharing the name you're searching on.

However, I believe the clang_complete plugin provides the functionality you seek. It makes use of the clang compiler to find the function that actually matches the one you are searching for, and not just one that shares the same name. It will override the ctrl-] functionality of ctags.

I have also seen it stated that YouCompleteMe renders clang_complete outmoded, but as I have yet to use it myself, I cannot guarantee its utility.

clang_complete git repo: https://github.com/Rip-Rip/clang_complete

  • I can't tell about clang_complete, however, YCM cannot find a function definition defined (sic) in another translation unit. We have (/had) clang-indexer (not really maintained), and a few other plugins. Nowadays, I'd say to check clangd + plugins implementing Language Server Protocol. – Luc Hermitte Oct 11 '17 at 16:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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