How to navigate in large project in VIM
Asked Answered
S

12

90

How do you manage big projects (hundreds of files) using only VIM?

I personally start having problems in any larger than small project.

  • is there any way to quickly 'go to file', preferably with name completition?
  • same for 'go to class definition', when it is in another file

I kinda know all the VIM basics, so I don't have problem using it for writing scripts or quick editing some source code. But it gets really messy for me when I have to navigate between files.

Sibilant answered 22/9, 2009 at 0:15 Comment(5)
What language are you using ?Imre
I'd prefer language agnostic solution, but I need support for C++, PHP and Rails.Sibilant
Which answer did you accept? @JakubArnoldAsarum
@xetrasu I ended up using NERDTreeSibilant
I use silver searcher github.com/ggreer/the_silver_searcherCrabby
R
35

VIM has excellent support for tags. Once you have created a tags file for your project, you can jump to a definition or declaration of a method, class, etc., including jumping across files, all inside the same editing session.

Try

:help tags

To generate a tags file for C/C++, go to your shell prompt (I'm assuming your system is *nix/Cygwin) and type

info ctags

or

ctags --help
Riffraff answered 22/9, 2009 at 0:21 Comment(2)
Vim also has support for cscope, which will let you do things like find what functions call a given function - see :help cscope for information. There's a nice feature list in the introduction (under "It is designed to answer questions like").Aker
Unfortunately, cscope has a very limited understanding of C++.Moujik
B
30

I like simple solutions, my favorite way to navigate at the moment is:

Add to ~/.vimrc.local

set path=$PWD/**

Then type this in the editor to find the file anywhere in the current working directory (pwd)

:find user_spec.rb

You can use tab-completion on the filenames to find multiple choices as well, making this TextMate convert very happy.

Braithwaite answered 12/9, 2011 at 12:21 Comment(2)
This solution is much simpler than :FC and plugins 'cos no caching is necessary and ... you made my day avocade! Thanks!Bicycle
Vim isn't reading the wd as the default directory. I've restarted the shell and it still doesn't work. Also tried vim . before executing the command :/Supplement
C
14

I use a combination of NERDTree (directory sidebar), FuzzyFinder Textmate (go-to-file like TextMate's CMD+T), and Sessions (:h sessions) to help me deal with large projects.

I would suggest using some sessions helper plugin. I would mention what I use, but I'm not satisfied with it yet. Just Google "vim sessions".

One thing to note with getting FuzzyFinder Textmate to work is that it depends on an old version the FuzzyFinder plugin, specifically v2.16. Anything higher and you'll get errors. But it's definitely worth the trouble. While it doesn't have name completion, its search is smart so if I search for fro/time/actionsphp it will pull up the file apps/(fro)ntend/modules/(time)_tracking/actions/(actions).class.(php) (parenthesis denote what it's matching). It makes it very easy to pick out files that are only unique by their folder name.

Callis answered 22/9, 2009 at 0:35 Comment(2)
I've found a new plugin that I like better and is easier to setup (at least in my case): CommandT. Much faster.Callis
A newer, more powerfull tool, writter in vim script, so no external dependencies is ctrlp used by the janus projectAlejandrinaalejandro
E
7

As well as the invaluable ctags and the various associated commands. I also couldn't live without the project plugin, which allows you to have the files of interest associated with a project in a separate pane. I can't remember how much of my setup is customised, but if I want to open a source file called Debug.c, I hit:

<F12>     " Opens the project pane
/De       " Searches for "De", which is likely to be enough to find Debug.c or possibly Debug.h
<ENTER>   " Opens the selected file and closes the project pane

I often then do:

:vsp      " Vertically split the window
<F12>     " Reopen project pane
#         " Search back to find previous entry with the same name (to find
            Debug.h if I was on Debug.c: my headers are in Headers/ and
            my source is in Source/, so the headers come earlier in the list
            than the source).  I use * to go the other way, obviously.
<ENTER>   " Open the header file in the other window and close the project window.

With this relatively short sequence, I can open any file and it's header in a vertical split. Since the project plugin window is just a text file, completion is achieved by using Vim's searching capability.

Exordium answered 22/9, 2009 at 10:24 Comment(0)
S
4

Starting in Vim 7.3, the :find command has tab-completion of filenames.

So if you set your 'path' option to contain your entire project (probably using the ** wildcard to allow recursively searching subdirectories), then you can use the :find, :sfind, :tabfind, etc. commands with completion to get to any file in your project. This also allows jumping to files directly with gf and friends if the file name is in your text, for example in an include directive.

With this method, no external tools or plugins are needed for navigating to specific files. Although, it may admittedly not be as fast or easy to use, and doesn't address the need for jumping to definitions. For definitions, I use ctags as other answers suggest.

Seriate answered 19/8, 2013 at 22:10 Comment(0)
S
3

If you are using ctags as other posters have recommended, then make sure you look at the taglist plugin.

Make sure you take the time to read the docs and learn the key bindings. Here are a few to get you started (from the TList window):

  • o - open file in new window
  • t - open file in new tab
  • [[ or backspace - previous file in list
  • ]] or tab - next file in list
Smoko answered 22/9, 2009 at 11:4 Comment(0)
C
3

Exuberant ctags.

Use Ctrl-] to jump to the tag under the cursor.

Copro answered 24/9, 2009 at 15:21 Comment(0)
P
3

Opening vim from root of your source file and extending path option to include all sub-directories therein.
For example set path+=/usr/include/c++/** for C++ headers and set path+=** for your source directory.

This ,then, opens a plethora of following possibilities.

1) Opening file by name or parts of it

:find file_name

You can use auto-completion and wildcard expansion with :find reliably. You type the name, it will locate the name. This works language agnostic.I am sure you will like it.

2) Navigating to files under cusror:
if you want to go a file path like #include "project/path/classA.h.

gf or gF  - go to file under cursor.   

Ctrl-6 - to come back to last cursor position after gf or gF

3) API lookup and navigating to the API location

[i or [I can be used to look up your function signature for word under cursor without leaving your workspace. [<Tab> to actually go to declaration. Use Ctrl-6 to come back to last location.


Without extending path, you can start navigating files by :Ex command and navigate and open your file. I prefer NerdTree over this though.

Pase answered 27/1, 2016 at 14:7 Comment(3)
Thanks, path option is very powerful. where to find docs about [<Tab>, couldn't find it anywhere?Namnama
[<Tab> I got it from Bram Moolenar's 7 seven habit of highly effective editing, I thinkPase
Thanks. Found it moolenaar.net/habits_2007.pdfNamnama
K
2

I use FindFile. If you open vim at the root of your project and run :FC . the plugin will cache all the filenames beneath your cwd. You can then do :FF to open a completion menu and type the name of the file you want (or rather, the first few letters).

Kathline answered 24/9, 2009 at 15:14 Comment(3)
wow this is like the easiest plugin to use. Zero setup involved.. just FC . in your root dir, then :FF enter, start typing the file name you want and you're done. I am trying to figure out how to launch in new tabs still though..Paraformaldehyde
also worth noting that if you use this, every time you launch vim, you'll need to redo the :FC . to cache files in that directory.Paraformaldehyde
Here's an updated version of FindFile.vim with :FT or :FindTabNew gist.github.com/1104884Paraformaldehyde
S
1

Although I'm kinda hoping someone will point out a better solution so I can learn something, NERDTree has been good to me for getting to specific files with name completion as long as I have the tree expanded. The command when I need to get to a file is something like:

,d/foo.pyo (where foo.py is a file name)

,d to open the tree, / to enter search mode, the name (or partial name, or regex, or whatever) of the file, and then o to open.

Of course you may have to hit 'n' a few times if you didn't type enough of the filename or there are duplicates.

I admit it feels like a bit of a hack using NERDTree like this although it has gotten so far into my muscle memory by now that I don't even think about it.

Of course I use ctags too but those are only useful when you have a function near the cursor and need to get to its definition in another file or something. A lot of times I say "OK, I need to work on feature x now" and need to navigate to another file without any references nearby that ctags would really help with.

Subito answered 22/9, 2009 at 1:12 Comment(1)
I looked into it some more, fuzzyfinder looks like a great idea for project search.Subito
M
1

I'm using two plugins of mine:

  • searchInRuntime that completes filenames on command line. It is somehow similar to fuzzyfinder and lookupfile,
  • lh-tags which is completely experimental and undocumented. It offers two features: automatic and quick update of the tagfile on file save(ing?), and a tag selector plugged to <c-w><m-down> by default. You may want to check the renowned taglist plugin instead.

Both require my viml library lh-vim-lib.

Moujik answered 22/9, 2009 at 6:21 Comment(0)
R
0

Try SourceCodeObedinece. This one I developed to handle C++ 1Gb source files project.
I use it in pair with 0scan.

These two plugins are wrappers around the most popular Vim browsing tools: ctags and cscope.

Radiative answered 23/9, 2009 at 19:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.