My blog has been moved to ariya.ofilabs.com.

Wednesday, July 16, 2008

vim: lightning fast navigation in a large software project

Love vim but need to work with a large software project that spans a dozen subdirectories and a bazillion source files? There are plenty of solutions, vim scripts or external tools, for this particular problem. Here is one that I've used for years: using the marvelous project script.

It comprises one .vim file (the script) and .txt file (the documentation), thus dead easy to install. After that, just launch vim using: vim +Project (replace vim with gvim if you favor the GUI version), the side pane will be visible. There is where the project tree will be displayed.

For a quick start, type \C and you will be prompted to answer 4 questions, as the example below (my answers are in bold)

Enter the Name of the Entry: KOffice
Enter the Absolute Directory to Load:/home/ariya/koffice/source
Enter the CD parameter:
Enter the File Filter: *.cpp *.h *.c

which, as you might guess, create an entry with the given name from all C/C++ headers and sources from the specified directory. Wait a few seconds (or minutes, depending on the project size) for the script to scan files in your disk, at last it will show the tree (as in the screenshot above) in the project window.

You can, of course, add as many entries as you want.

Note: for optimal usage, do not forget to put this on your .vimrc file:

:let g:proj_flags="imstvcg"

For details on the meaning, see the script documentation.

Navigating the project tree is easy, if you are familiar with the vim folding. In principle, use zo and zc to open and close the fold right where the cursor is located, or zO and zC to apply it recursively, i.e. for the whole entry.

How to open a file? Just place a cursor in a file name and press Enter. Since the project window is just a normal window, switching back and forth between the project window and main editing window is as easy as Ctrl+W w. Or you can use F12 to quickly show and hide the project pane. In addition, pressing Space toggle the wide and small version of project pane.

Some more tricks. Because the project window is just a normal vim window, use the blazing fast incremental search (along with n or N) to spot the file that you want. It even does allow you to jump between different matches quickly. Again, if the project window is too narrow, hit Space to make it wider and another Space will return the width back to normal. If you press Enter on a filename to open it, a wide project window is toggled to the usual width automagically. Master this technique and you will open any file you need in an instant.

Because I love tabbed editing, I also have this in my .vimrc:

:map <C-T> <Esc>:tabnew<CR>

so that Ctrl+T opens a new empty tab. Wherever I am, I can open KSpread's Cell.cpp (to have a quick look, hence in a new tab) as fast as hitting Ctrl+T, F12, /Cell.cpp, Enter. Try to beat that.

But that is not all. You might ask: what's the use of a big file list if I don't know which file I need to open? Right, because everyone (and his dog) just needs grep. Use \G (which will use vimgrep) and type in your search string. After a while, all the matches are listed in another small window. Choose one that you want and hit Enter, all the magic ensures that the corresponding file will be opened and the cursor is right located in the matched line.

For more features, e.g. rescan the files from disk, adjust the pane width, execute a command on a file, non-global project tree, etc., refer to the script documentation.

Untap the potential of this wonderful vim script and a 3000-files project is not a burden anymore!

27 comments:

Anonymous said...

Thanks for these useful tips! I love vim, but for larger projects I always used Eclipse up until now. For the next project, I will reconsider vim using the Project plugin. ;-)

Anonymous said...

I made a script in perl to spawn a .genvimprojects file.
Maybe you find it useful.
You can get it from here.

Anonymous said...

Since I saw it on your screenshot: how do you add this nice grey line at the bottom of the vim window? I have it, but somehow I'm not able to reproduce that on other computers...

Anonymous said...

@liquidat: set laststatus=2

Anonymous said...

To avoid getting the "Press ENTER" message whenever I open a file:
:help press-enter
:set cmdheight=2

Anonymous said...

Sounds interesting, but i'm a noob using vim only for some config file editing so far.
What do you mean with "press \C". If i press Backslash C nothing happens. Can you help me? I am using vim 7.1.314 on debian testing with a german keyboard layout.

Dmitry said...

Nice post, but why don't you use tags? :)
With tags I can beat your opening of Cell.cpp by just typing ":tag Cell"

Personally I find that tags are all I need to navigate in a project of any size.

But in the end everyone uses what feels comfortable to him of course :)

Anonymous said...

I would like to know if there is any autocompletion for methods, variables in vim for C++, I am already using ctags-exuberant, but still I dont get dropdown list like:

vector v1;
v1.{dropdownlist of methods for vector}{argument list for method}

I am still looking for something that is equivalent java-autocomplete in Eclipse for c/C++

I have tried to get C++/C autocomplete etc with tags/etags/imenu in vim and emacs, but none compare to the likes of java on eclipse.

any suggestions?

Anonymous said...

c++ completion:

http://www.vim.org/scripts/script.php?script_id=1520

Anonymous said...

Really impressed with this, but what I'd really like is to have the project buffer open on the left regardless of which Tab is open on the right. I can't think where to begin with that though - any suggestions?

Anonymous said...

i have tried the c++ completion, but doesnt work as suggested on the website, i dont get method popups for say
vector v1;

v1.{no related {method} popup here, but rather lots of other functions/variables}

i have already generated c/++ tags with ctags-exuberant

Anonymous said...

You might want to check out VimMate. It wraps gvim with a ruby script to show the file list. Still not perfect though as it doesn't like large project directories. I would still like to find something like you mention that doesn't have the file limitations.

Does anyone know of anything along those lines?

Ariya Hidayat said...

@Anonymous: did you install the project script before trying backslash C?

@Dmitry: I use ctags a lot and plan to blog about it separately. This one is only about opening any file you already know.

@Anonymous: the autocomplete works fine for me, at least for Qt classes. I'll put a quickstart when I find time.

Anonymous said...

@ariya_hidayat:

I'm looking forward the ctags article. I'm still confused how to use ctags when the search path span directories above the current file that's being edited in Vim. Any clues?

Anonymous said...

Thanks a lot for sharing this. I really love it.

Unknown said...

Ariya wrote: Wherever I am, I can open KSpread's Cell.cpp (to have a quick look, hence in a new tab) as fast as hitting Ctrl+T, F12, /Cell.cpp, Enter. Try to beat that.

Textmate can beat it: Cmd+T, cell, Enter. But, I guess you need to code KSpread on Mac :-)

Ariya Hidayat said...

@rian: you can do that (Ctrl-T and start searching) with vim as well, see http://tinyurl.com/5sqn5j

Anonymous said...

hi
could you tell me what excactly should happen if I press \C ? My left pane simply goes into insert mode. If I fill out 4 lines as you describe nothing happens, also \r won't reload anything. What I'm doing wrong ...
thanks

Ariya Hidayat said...

@Ben: \ is the leader character. You can map it to something else and see whether it works, e.g.
:let mapleader = ","

viagra online without prescription said...

I'm using vim only for some config file editing. I will try use more vim!

Zaheer said...
This comment has been removed by the author.
Zaheer said...

Ariya, Interesting. An alternative to Ctrl+T is to split the right window (vsp) and highlight the window and open the file in that.

Is there a way you can store the session so that you dont have to create the content (\C) everytime.

Anonymous said...

I wish the project plugin supported regular expressions for filtering instead of just globs.

Anonymous said...

I would not remap Ctrl-T from its default (go to previous entry in tag stack).

And I would like to recommend the Command-T plugin for easy access of files in large projects; see https://wincent.com/products/command-t (it has a screencast).

Ariya Hidayat said...

@Daniel: See also http://ariya.blogspot.com/2011/02/vim-fast-file-navigation-with-command-t.html

tec said...

Thanks for the useful links. They work surprisingly well. Just one question: F12 does not toggle the project pane in my vim. Do you have an idea where I could start looking for the reason?

custom logo design said...

Hello ,This one is only about opening any file you already know.