Tag Navigation

Jump to definitions across files using a tags index.

Keys: Ctrl-], Ctrl-T, :tag, :tags, :tnext, :tprev

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

The core two keys
KeyNote
Ctrl-]Jump to the definition of the identifier under the cursor
Ctrl-TPop back to where you came from (one level)
:tag NAMEJump 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

Browse the history
KeyNote
:tagsShow the full tag stack with current position marked
:tnextNext match when the tag was ambiguous
:tprevPrevious match
:tlastLast match
:tfirstFirst match

See also: The Jump List