gospelunk: quickly find definitions in go projects!

Update 2023-01-09: gospleunk has changed significantly since this post was written. It now uses the built-in Go parser and type-checker to implement “find definition,” “find-references,” and more! See the post implement “find definition” in 77 lines of go for more details.

A while back, I described an idea for a CLI tool to find definitions in Go projects, and now I’ve built it! I also gave it a shorter name: “gospelunk”, as in “spelunk through some Go code.” It’s similar in spirit to ctags, except that gospelunk understands Go dependencies and can re-index a large project in seconds instead of minutes.

The project is open-source under the MIT license and available on GitHub.

This demo shows how to use gospelunk index to build a search index, including packages imported from other Go modules and the standard library.

The bash function gofind is defined as:

gofind () {
  # find matching definitions, let the user select one using fzf, then open the file in less.
  gospelunk find -i -f "+{{.LineNum}} {{.Path|RelPath}} {{.Kind}} {{.Name}}" $@ \
  | fzf \
  | cut -d " " -f 1-2 \
  | xargs less
}

Here’s another demo showing how gospelunk integrates with aretext, the vim-compatible text editor I’m building. I’ve added a custom menu command to call gospelunk find for the word under the cursor:

I like how quickly this allows me to jump between packages, including ones imported from the Go standard library (like net in the demo above).

For now, the project status is “alpha”: the interface may change, and there are probably some bugs I haven’t found yet. But, if you’re interested, please try it out!