Tag Navigation
Jump to definitions across files using a tags index.
ctags builds a tags file mapping symbols to file:line. Ctrl-] jumps to the symbol under the cursor; Ctrl-T pops back. The whole jump history forms a stack you can browse with :tags.
Long before LSP, Vim had a 'go to definition.' It still works โ and on big codebases it's faster than any language server because it's just a binary-searchable text index.
Build the index
Run a tags generator (universal-ctags is the canonical one) at the root of your project:
| Command | Effect |
|---|---|
| ctags -R . | Recursively index everything under . into a file called tags |
| ctags -R --languages=python,go . | Limit to specific languages |
| ctags -R --exclude=node_modules --exclude=.git . | Skip noise |
Vim looks for the tags file in the current directory, then walks parents. Configure with :set tags=./tags;/tags to search both adjacent and root tags files.
Jump and return
| Key | Note |
|---|---|
| Ctrl-] | Jump to the definition of the identifier under the cursor |
| Ctrl-T | Pop back to where you came from (one level) |
| :tag NAME | Jump to a named tag (Tab-completes) |
| g] | Show menu of all matching tags (when the name is ambiguous) |
| Ctrl-W ] | Open the tag in a new horizontal split |
| Ctrl-W } | Show the tag's definition in a preview window without leaving |
The tag stack
| Key | Note |
|---|---|
| :tags | Show the full tag stack with current position marked |
| :tnext | Next match when the tag was ambiguous |
| :tprev | Previous match |
| :tlast | Last match |
| :tfirst | First match |
See also: The Jump List