Using multiple tag files at once in vim / Tag organisation in general
Asked Answered
E

1

6

(Apologies for the C tag, I did it for the syntax highlighting. This is more of a vim question. If someone more learned than I thinks the tag should be removed please do so)

Say I've got this directory structure:

Directory ~/Code/Test/     containing file1.c file2.c file4.c and Sub 
Directory ~/Code/Test/Sub/ containing file3.c

file1.c:

#include <stdio.h>
#include "file2.c"
#include "Sub/file3.c"

void function1();

int main (int argc, char *argv[]) {
   function1();
   function2();
   function3();
   return 0;
}

void function1() {
   printf("1\n");
}

file2.c:

#include <stdio.h>

void function2();

void function2() {
   printf("2\n");
}

Sub/file3.c:

#include "../file4.c"

void function3();

void function3() {
   printf("3\n");
   function4();
}

file4.c:

#include <stdio.h>

void function4();

void function4() {
   printf("4\n");
}

In any one of those files it should be possible to jump to the definition of the functions it uses from the other files. So for example, file1 should be able to jump across to file2, file1 should be able to jump down a directory to file3, file3 should be able to jump up a directory to file4, and here's the kicker; all of the files should be able to jump to the definition of printf. I also shouldn't have to copy the tags for the c library implementation into the Test directory in order to do this.

I'm wondering how I could go about doing this. I'm really not keen on monolithic tags files. Having a vim-wide tags file horrifies me. A tags file per directory annoys me. A tags file per project is bearable. But what I'd really like is a tags file per source file, and then a way to specify which tags files vim should be referring to.

Ideally I'd like to be able to just ctrl-] on anything and have vim jump to the correct definition based on what's in scope, just like visual studio. I'm beginning to suspect this can't be done, and if it is (via some combination of plugins) it would be extremely slow, which is really annoying because I was totally on the "Vim can do anything your newfangled IDEs can do" bandwagon for a couple of weeks there. Yes it's definitely the most powerful text editor I've come across, but as an IDE it's extremely unpolished. When I use the "Go to definition" command I expect to be taken to the correct definition whether it's a local variable, in a different file, in a standard library etc. Vim so far has given me hilarious results such as jumping across from a java file to a c file. And you have to use a separate command to jump to the definition of a local variable... What? (If there's a reason behind this I'd be interested in knowing)

I'm aware of wacking set tags=./tags in my .vimrc and that's what I've done so far. But this won't scale if I work on something massive that links separate assemblies and source files from separate projects together.

(To be fair to vim, visual studio doesn't let you jump across assemblies to find definitions either, but it does at least have the good grace to serve up a header file from which you can "load assembly" and navigate to the actual source code you're looking for)

Epimenides answered 27/6, 2013 at 6:37 Comment(2)
possible duplicate of Can ctags be made to follow #include directives?Ganoid
I suggest you not to deal with ctags manually, but use plugin Indexer instead ( www.vim.org/scripts/script.php?script_id=3221 ). It provides painless auto-generation of tags for one or several projects and keeps tags up-to-date.Prettypretty
G
-18

First things first: Vim has never been, is not and will probably never be a proper alternative to an IDE. Whoever made you believe that should be shot and you should be shot too for believing such nonsense.

I'm only half-joking.

Vim is a very powerful programming-oriented text editor but the simple fact that you need to run a dumb external code indexer to get a dumb "jump to definition" or another code indexer to get another dumb "jump to usage" should be a hint that Vim can't realistically be compared to an IDE. Hint: the I in IDE means "Integrated" and the E means "Environment". Since you can't get proper integration and would be hard-pressed to consider Vim as an environment, there's no IDE, here. Only a text editor with many plugins doing different things in different ways and, above all, no serious way to understand your code which is the #1 feature of a descent IDE.

Many users/bloggers claim they are using "Vim as an IDE" or that you could, too, turn Vim into a Python or whatever IDE but the truth is that Vim lacks all the low-level features that would make such a thing possible. You can turn it into something that looks like an IDE, if you are somehow able to believe in your own lies, but it will probably never be an IDE.

Whatever…

  • The default behavior (which can't be altered in your configuration) of <C-]> or :tag foo is to jump to the first hit in your tags file(s). Neither Vim nor Ctags know about scope. At best, you can be treated with a list from which to choose the correct tag (:ts foo or g]) but that's how far you can go.

    Depending on the languages you work with, Cscope might be better at indexing your code but the general principle is the same as with Ctags. Cscope offers a "jump to usage" feature so it might be worth switching just for it.

  • Making sure the correct tags file(s) are used can be a pain and the doc is surprisingly not very helpful in that regard. There are a bunch of plugins designed to make it simpler that you could try, EasyTags comes to mind.

    I admit I don't work on very large projects and not even in C so maybe this won't seem useful but this line in my ~/.vimrc makes working with tags easier:

    set tags=./tags;/,tags;/
    

    With this setting, Vim looks up and up (non-recursively) until / for tags files. The main point of this is to have a single tags file at the root of each of my projects that can be used from every file in that project without ever needing to tell Vim where to look for a tags file.

    One way to deal with your Java/C mixups could be to put your projects into language-specific directories:

    C/
      c.tags
      proj1/
        tags
        …
      proj2/
        tags
        …
    Java/
      j.tags
      proj3/
        tags
        …
      proj4/
        tags
        …
    

and put you "global" tags files at their root as well as project-specific tags files at the root of their respective projects.

Another way to deal with that issue could be to instruct Vim to load specific tags files depending on the filetype:

    autocmd FileType c setlocal tags=/path/to/your/global/c/tags,./tags;/,tags;/
Gleason answered 27/6, 2013 at 7:39 Comment(9)
Feel the hate flow through you... no but seriously, with the correct set of plugins you can usually get all the functionality that you would actually WANT from an IDE without having all the bloat and stuff you don't want. With an IDE you get all of it or nothing. With VIM you can basically put together an "IDE" that has the exact features you want. The best part? If there is no plugin out there that does what you want, it's not that hard to write your own.Surf
@eeeeaaii, you are free to believe your Vim and all your plugins together form an IDE. I believe it's just a text editor bloated with subpar IDE-like features. The OS is the development environment and Vim is its text editor component.Gleason
Some very good points made, one completely inaccurate statement, some helpful tips, but an overall dangerous and damaging message. The points about neither Vim nor ctags taking context into account, and how Vim looks for a matching tag is very important to understand when trying to use tags to get a good code definition lookup working. The tips about different ways to setup tags are helpful. The statement that "The default behavior (... can't be altered in your configuration) of <C-]>" is just plain wrong. I used to have it altered in my config.Hollis
This is a dangerous message to spread because the more people buy into the idea that because Vim is a text editor, therefore it cannot achieve something like an IDE level quality for code definition lookup, the more this becomes a self fulfilling belief. Vim cannot provide context driven lookup WITHOUT a plugin or very advanced configuration that does it. What we need is more people working on such plugins, not pessimism about what Vim can do. Now if you want to provide evidence of inherent limitations that make it almost impossible to make such a plugin, this may prove to be helpful.Hollis
The first two paragraphs are not needed and should be removed from this 'answer'.Petiole
I would recommend you to add the phrase "In my opinion..." to the beginning of your answer. Because it is your opinion, which is pretty controverse, and you might not want to sell it as if it was the eternal truth.Cathrin
Is there anything wrong to put your own opinion on the table when answering someones question? This answer was very helpful to me and I can strongly relate to both of the clashing though flows around here. Yes you can setup your development environment in numerous ways. But favoring an IDE or not doesn't give a you a right to stomp on someones way of doing things and his way of thinking.Bucentaur
@Bucentaur SO is in general against opinions, which includes both questions asking for opinions and answers expressing opinions. This is a good thing, IMO. But people are people and they don't like having their bubble burst so they downvote the truth and call it "opinion". C'est la vie.Gleason
Yeah, I just hate to see voting systems misused and exploited. My background is games and you see that a lot on platforms like steam where users try to push through their own agenda using down voting as a weapon against developers. Who lose users and money because of it. Its straight up the worst thing that can happen to any platform SO included. SO is full of opinions, come on, software development is more of a religion at this point and many so called "facts" are just down right personal opinions anyway. Thanks for the writeup. Much appreciated!Bucentaur

© 2022 - 2024 — McMap. All rights reserved.