tags:

views:

335

answers:

4

I want to be able to start up vim in an arbitrary subdirectory in my project and have it search up to the project root for the tags file, and then to search in an unrelated directory outside the project tree.

For example let's say I have the following:

~/projects/foo/bar/baz.c
~/projects/foo/tags
~/some/arbitrary/path/tags

I want to open baz.c from within the bar subdirectory, have it search up to find foo/tags and then to search some/arbitrary/path/tags if the symbol isn't found in foo/tags.

Now I know I can do:

set tags=./tags,tags;

to accomplish the first task. It's apparently the semicolon which tells vim to search up to the root. However neither of the following work:

set tags=./tags,tags,~/some/arbitrary/path/tags;
set tags=./tags,tags;~/some/arbitrary/path/tags

The first one finds only symbols from ~/some/arbitrary/path/tags while the second one only finds symbols in the tags file at the project root.

Anyone know how to do this? I'm on Linux buy the way.

A: 

replace the tilde with path to your home.

just somebody
Sorry, doesn't work. I tried both `set tags=./tags,tags,/home/myuser/some/arbitrary/path/tags;` and `set tags=./tags,tags;/home/myuser/some/arbitrary/path/tags`
Robert S. Barnes
how are you testing it? What exactly is happening? I created a tags file in a programming directory of mine, edited my .vimrc to include that path in "set tags", using the tilde as the starting point. Then, I made a dummy file, test.c, in my home directory (so, not in the directory with the tags file), wrote the name of a function that would be listed in the tags file, and pressed "ctrl-]" with the cursor over the function. Took me right where it was supposed to.
Derek
I set the search path manually inside vim. I test by looking for two symbols, one symbol from a separate file in the same project whose tags file is a few directories up in the project root, and then looking for a symbol from the external tags file on the arbitrary path. Depending on which version of the path I use I find one symbol, or the other, but never both.
Robert S. Barnes
A: 

Your first "set tags" option works for me in Linux. (As in, I've done it before, and I just recreated it to be sure.) You can have many different paths in your tags option, both absolute and relative. However, in the second one, you have a semicolon in the middle of the list, which is incorrect. In fact, you don't need any semi-colon. I would also replace the ~ with the absolute path to your home, just in case, and remove the semicolons all together. Just have commas between each path.

Oh, and to search up a directory for the tags file, you need "../tags", not "./tags". A single dot means the current directory, two dots means the directory one up from where you are.

Derek
Could you post exactly how you recreated it since I can't seem to get it to work.
Robert S. Barnes
Are you opening the file from the project root or from the subdirectory? I'm opening the file from within a subdirectory in the project, not the project root.
Robert S. Barnes
This is what I have: set tags=./TAGS,./tags,tags,TAGS,~/programming/mandelbrot/main/tagswhere the last directory is the absolute path. As I mentioned above, it won't search in any parent directories, since I'm not using ../tags.
Derek
I'm specifically trying to search up to the project root from the current directory. That's what the semicolon in `tags=./tags,tags;` allows. Unfortunately, I can't seem to figure out how to get it to both do that and **then** search the second external path if the symbol wasn't found. I need to search up to the project root because I might be in some directory of arbitrary depth in the project. My OP was a very simplified but representative example.
Robert S. Barnes
A: 

Is the tags file always in the project/ directory? If so, you don't need to "search up" to find the tags file. Just hard code the path to both files like this:

set tags=/home/you/projects/foo/tags;/home/you/some/arbitrary/path/tags

If not, you can try something like this:

set tags=/home/you/projects/**;/home/you/projects,/home/you/some/arbitrary/path/tags

I haven't tried this so you might have to experiment with it. There are some pre-conditions for it to work. See :help file-searching.

Steve K
+2  A: 

I use:

set tags=~/.tags
set tags+=~/.vim/tags/cpp
set tags+=~/src/git/gitsrc/tags
" and so on...

For generating tags in a particular project's root:

map <C-F12> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR>

I adapted this setup from the C++ code completion vim tip.

Greg Bacon
Splitting the set command up into multiple lines solved the problem for me. I ended up with `set tags=tags;` in my `.vimrc` and then typing `:set tags+=~/some/arbitrary/path/tags` from within vim.
Robert S. Barnes