Dis-Integration

So, if I’m not really happy with IDEs, what can I do to improve my development environment? Well, I’ve discovered a few other tricks…

vi Tags

Although Vim doesn’t have anything really comparable to a class browser or VS’s Intellisense, it does have ‘tags’, which have long been a part of most vi variants. Basically, if I position the cursor over the name of a type/class/function/etc. and want to know more information about it, I can type ‘g<Ctrl -]>’ and Vim will display a list of places where that symbol is declared or defined. I can select one of them and it’ll load that file and jump to its position there, and then I can hit Ctrl-T to return to where I was originally. That makes it very easy to jump to a class’s definition or a function’s prototype and accompanying documentation without having to remember which file it was in, find it in the source control tree, open it in a new window, and search for it.

The main disadvantage of tags though, and the reason I hadn’t been using them in the first place, is that they’re not automatic; they require you to generate an external ‘tags’ file and configure Vim to look for it. This can be a pain to do, especially when you’ve got multiple projects whose tags you don’t want mixed together.

However, Vim has a couple features that alleviate some of this and allowed me to get a workable solution together. First, Vim can load tags from multiple files, so I separated our source trees into three different areas: common libraries used by all projects, third-party libraries and components, and individual projects. Each of these gets their own separate tag file, to cut down on the amount of regeneration of tag files that has to be done (the project tag files might need to be updated frequently, the common libraries less often, and the third-party one rarely).

Then, I set up some scripts to generate the tag files automatically. All this really is is a set of batch files for each of the above areas, set up to run the tag file generator (I use Exuberant Ctags for this) recursively on a particular chunk of the source tree and places the resulting tag file in a specific location. I also set up a scheduled task to run at 2am each night to automatically run these scripts and regenerate the tag files each day.

And finally, Vim has to be able to find the tag files. This is set via the ‘tags’ variable within Vim, and the common and third-party library tag files are in a fixed location, so I just had to add those locations to that variable in the .vimrc file. Project-specific tag files are a bit more difficult, but Vim has a feature to handle this, too: if you specify “tags;/” as one of the paths to search, Vim will look in the current directory and all of its parent directories for the file named ‘tags’. Thus, all I had to do was make sure the ‘tags’ file for each project was in the root directory of that project’s source tree, and Vim would walk up the tree and find it if I was running Vim from within that project’s directory tree.

Editor Window Consolidation

I have Perforce set up to launch Vim on a source file by double-clicking it, but it brings it up in a new instance each time. It doesn’t take long before I’ve got 20+ Vim windows open, sometimes with the same file in different windows.

To reduce the clutter a bit, I’ve set it up so that it uses the ‘remote server’ support in Vim (by adding the ‘--remote-silent‘ parameter) to cause it to open files in an already running instance of Vim, if there is one, rather than starting a new one. Then I only have one Vim window and can just use the Vim buffer menu to switch between the files currently loaded. There was one other quirk here; normally Vim doesn’t allow you to switch buffers if you’ve modified the current one and not saved it yet, but adding “:set hidden” allows you to do so.

I’m not entirely happy with this one yet, though. All too often I forget that I have multiple files loaded and go and close the Vim window, and then a few minutes later wonder where my build output log vanished to… It’s possible to use different server names to separate files into different categories so that say, source files all get loaded in one Vim window, text files in a separate one, etc., but you have to use different launching scripts to do so and it still happens within that category of files.

It also makes it a bit harder to compare files side-by-side when they both get loaded into the same Vim instance. Vim’s internal window splitting can help, but is a bit more cumbersome to use. This can again be solved with a separate launcher that goes back to the old always-use-a-new-window behaviour, but then I have to remember to use that launcher in those cases.

Maybe one of these days I’ll give emacs a whirl and see if it can solve these same problems any better…

3 thoughts on “Dis-Integration”

  1. Alas, it cannot reveal the true nature of love.

    I hear you need to buy BBEdit for that.

Leave a Reply

Your email address will not be published. Required fields are marked *