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
{key:Ctrl-]}Jump to the definition of the identifier under the cursor
{key:Ctrl-T}Pop back to where you came from (one level)
`:tag``NAME`Jump to a named tag (Tab-completes)
{key:g}{key:]}Show menu of all matching tags (when the name is ambiguous)
{key:Ctrl-W}{key:]}Open the tag in a new horizontal split
{key:Ctrl-W}{key:}}Show the tag's definition in a preview window without leaving

The tag stack

Browse the history
KeyNote
`: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