Tags Vim

Two tools I find very useful when navigating large C code-bases with Vim are ctags and cscope.

ctags allows easily jumping to tags - function, macro and variable definitions. The excellent taglist plugin of Vim uses it to create an IDE-like listing of all the tags of your buffer in a separate mini-window. It's also required for the implementation of omni-completion in Vim (kind-of intellisense).

cscope is somewhat more versatile. In addition to jumping to tags, cscope allows you to find where a function is called, where a variable is assigned, what functions the current one calls, and a useful general C symbol lookup. In browsing the 300+KLOC CPython code-base I found cscope to be extremely functional and helpful in untangling relations between functions and finding what calls what.

While trying to use these tools for Python code, however, I ran into a few problems, some of which I didn't yet solve.

ctags for Python

At first ctags appears to work find for Python code, managing to find symbols in a large code-base. However, very quickly one notices an annoying problem: tags are created for imports, not only function / class definitions. Suppose you define a class named MyType in a file mytype.py. Other files import it by running:

from mytype import MyType

Now, when your cursor is on MyType you'd expect Ctrl+] to jump just to the class definition, but it actually asks you to which of several tags you want to jump, and apart from the definition, there's a tag for each import. This can be very annoying...

Fortunately, there's a way around it, which took some googling to find. Create a file named ~/.ctags (if you don't already have it) and place the following line into it:

--python-kinds=-i

Rerun ctags. This tells ctags to stop marking imports as tags. ctags allows convenient configuration of such things, and you can examine these settings by using the --list-kinds argument. For example after adding the import exclusion line, I get:

src$ ctags --list-kinds=python
c  classes
f  functions
m  class members
v  variables
i  imports [off]

cscope for Python

(Edit: 28.09.2010) Note: this is no longer accurate. See my newer post on this issue.

cscope is a harder problem. Although its Wikipedia page explicitly states it supports Python and googling around you find some people suggesting to use it for Python, I just couldn't make it work.

Jumping to Python symbols with cscope is always shifted by a few lines. A short investigation led to the discovery of cscope's inability to grok Python comments, and lines starting with # confuse it and create the shift.

There's a tool online called pycscope, which claims to create an accurate cscope database for Python code, but it appears to be incompatible with the latest cscope.

I've written to one of the maintainers of cscope, who was surprised I'm using it for Python code at all, since the tool is designed for C code.

So if you've managed to run cscope on Python code, do let me know please.

grep and EasyGrep

So without cscope I was left with one of the oldest and truest friends of the programmer - grep. Fortunately Vim has a very nice plugin named EasyGrep that wraps the functionality of Vim's grep and provide simple means for searching source code.

A couple of EasyGrep's most useful features are:

  1. Creating key bindings for searching the symbol under the cursor.
  2. Automatically configuring grep to search recursively on certain file types, depending on the type of the current file. This functionality is fully configurable.

Anything else?

Any other plugins and tools you're using to make your Python coding in Vim more pleasant? Please let me know.