19

Can I jump to a function declaration or definition in a multiple C++ source files project?

Lets say I have a header file foo.hpp:

int bar();

and a source file foo.cpp:

#include "foo.hpp"
int bar() { return 42; }

and a main file main.cpp:

#include "foo.hpp"
int main() { bar(); return 0; }

Can vim find both the definition and declaration of the function bar() from the main function?

4 Answers 4

21

Exuberant ctags is the simplest way to achieve this. Under GNU/Linux (e.g. Ubuntu or Debian) you should be able to just do

sudo apt-get install exuberant-ctags

(For OSX "$ brew install ctags" should suffice; for Windows you might want to visit http://ctags.sourceforge.net/ and download the standalone executable)

Then navigate to your project's root folder and run

ctags -R --exclude=.git .

This will scan your entire project and create a ./tags file which vim will automatically use to provide you with the ability to jump to functions at the press of a key. Namely:

Ctrl + ]

with your cursor placed on the function you want to see the implementation for. There are other combinations and many command mode functions that let you navigate through your code by ctags as well (e.g. Ctrl+t to jump to older tag stack entry). See :help 29.1 for an overview.

Note that you have to re-run ctags for each significant change in the code and let it re-index your project. You can either do that manually, or teach vim to do it on hotkey or on write.

Hint: if you make extensive use of ctags, maybe the vim-taglist (http://vim-taglist.sourceforge.net) plugin is worth a look as well. It gives you an IDE-style outline with a list of all functions for that class/file.

1
4

So far I can name two solutions to the problem of finding either the declaration or the definition of a function. I know there is another well know tags based solution, but as I don't use it, I'll let others give it to you.

The more trendy one first: YouCompleteMe has a :GoToDefinition and a :GoToDeclaration pair of commands.

The one I use (it's hard to change 10years long habits). My lh-tags plugin has a way to generate a ctags database and to update it incrementally. And also it offers a way (CTRL+W Meta+Down) to present all declarations and definitions that match what is under the cursor (/what is selected). As this solution relies on ctags, it won't be able to know which overload the identifier under the cursor is really related too. Other ctags based solutions should as bad (/as good) on this topic. However YCM should be much better here.

Discl.: I did implement lh-tags as a more ergonomic alternative to :tselect.

(Actually I remember a third solution: I had started a fork of clang-indexer and the related vim plugin that would have encapsulated it. But with YCM around, I'd to forget this solution)

EDIT: As of 2019, the most efficient solution rely on LSP servers. I'm using COC+ccls to index, jump and do many more things. I'm falling back to tags based solutions when I'm too lazy to configure COC for a project on which I won't spend much time or where I cannot install recent versions of clang and ccls.

2
  • 1
    Thank you for the input, will test each solution. I tested the YouCompleteMe and only GoToDeclaration works with multiple source files. Here's a quote from the docs about GoToDefinition: For C-family languages this only works ... when the definition of the symbol is in the current translation unit.. Also, the commands are :YcmCompleter GoTo*. Commented Feb 19, 2015 at 18:03
  • I missed this line. That means that clang_indexer may still be useful. The other solutions may be a bit tricky to install. Don't hesitate to send me an email if need be. Commented Feb 19, 2015 at 18:16
3

There are few alternatives. The first one is ctags. If you need a more advanced indexer then cscope is a better alternative. For instance it will allow you to list all callers of given function. These tools will index your code without really understanding it properly (they do have a simple grammar definition to know what given symbol means). It's also relatively easy to extend that grammar. The taglist plugin is a must have for these and it's possible to extend indexer grammar to show results in taglist.

If you need something more than indexer then like syntax checking then YouCompleteMe is probably the way to go. It's build on top of the llvm and thus has proper parser. This allows to check the code syntax and semantics.

Then if you work with a code that has domain specific language or embedded code then you often end up just greping thru files. Alternative is Ack perl script that tries to help with this task.

0

I think that ctags it's what you need. Vim is integrated with ctags natively, and can jump easily to function definitions and declarations.

Take a look on this article http://andrew.stwrt.ca/posts/vim-ctags

1
  • Please add a summary of the linked post. Link-only answers become useless when the link goes dead.
    – muru
    Commented Feb 20, 2015 at 6:32

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.