Fuzzy search Go docs from within Neovim.
Tip
Extensible via adapters: bring your own language/data source (Python, Rust, dad jokes — whatever you want to pick).
Screenshot is showing the Snacks picker.
- Search and browse docs for Go standard library packages and project packages
- Go to definition from picker
- Optionally leverage
stdsymfor symbol search - Optional syntax highlighting via tree-sitter
- Supports pickers:
- Extend to other languages and data sources via adapters
- Neovim >= 0.8.0 (>= 0.12 if installing via
vim.pack) - Go installation with
go docandgo listcommands available
Pick whichever plugin manager you use. The plugin is initialized by calling
require("godoc").setup() — with lazy.nvim, opts = {} does this for you. See
Configuration for customization.
Using lazy.nvim
{
"fredrikaverpil/godoc.nvim",
version = "*",
dependencies = {
{ "nvim-telescope/telescope.nvim" }, -- optional
{ "folke/snacks.nvim" }, -- optional
{ "echasnovski/mini.pick" }, -- optional
{ "ibhagwan/fzf-lua" }, -- optional
},
build = "go install github.com/lotusirous/gostdsym/stdsym@latest", -- optional
cmd = { "GoDoc" }, -- optional
ft = "godoc", -- optional
opts = {}, -- see Configuration
}Using vim.pack (built-in, Neovim 0.12+)
vim.pack.add({
{
src = "https://github.com/fredrikaverpil/godoc.nvim",
-- Follow any tagged release. Omit `version` to track the default
-- branch (every commit, not just releases).
version = vim.version.range("*"),
},
-- Optional picker dependencies — pick whichever you prefer:
{ src = "https://github.com/nvim-telescope/telescope.nvim" },
{ src = "https://github.com/folke/snacks.nvim" },
{ src = "https://github.com/echasnovski/mini.pick" },
{ src = "https://github.com/ibhagwan/fzf-lua" },
})
-- Initialize the plugin (required), see Configuration
require("godoc").setup()Optionally install stdsym (enables
symbol search) on plugin install/update:
vim.api.nvim_create_autocmd("PackChanged", {
callback = function(ev)
if
ev.data.spec.name == "godoc.nvim"
and (ev.data.kind == "install" or ev.data.kind == "update")
then
vim.system({
"go",
"install",
"github.com/lotusirous/gostdsym/stdsym@latest",
}):wait()
end
end,
})Using vim-plug
" Optional picker dependencies
Plug 'nvim-telescope/telescope.nvim'
Plug 'folke/snacks.nvim'
Plug 'echasnovski/mini.pick'
Plug 'ibhagwan/fzf-lua'
Plug 'fredrikaverpil/godoc.nvim'
" Initialize the plugin (required), see Configuration
lua <<EOF
require('godoc').setup()
EOFThe built-in go adapter provides:
:GoDoc— open the picker and search packages.:GoDoc <package>— open documentation for a specific package or symbol.- In the picker, press
gdto go to the package definition (supported by Snacks and Telescope; for fzf-lua the keymap is<C-s>).
:GoDoc " browse all standard library packages
:GoDoc strings " view documentation for the strings package
:GoDoc strings.Builder " view documentation for strings.BuilderWarning
:GoDoc is also used by ray-x/go.nvim. To
avoid the collision, either pass remap_commands = { GoDoc = false } to
go.nvim or rename the godoc.nvim command (see
Configuration).
The plugin is initialized by calling setup() — any options you omit fall back
to the defaults below.
require("godoc").setup({
adapters = {
{
name = "go",
opts = {
command = "GoDoc", -- the vim command to invoke Go documentation
get_syntax_info = function()
return {
filetype = "godoc", -- filetype of the documentation buffer
language = "", -- tree-sitter parser, for syntax highlighting
}
end,
},
},
},
window = {
type = "split", -- split | vsplit
},
picker = {
type = "native", -- native (vim.ui.select) | telescope | snacks | mini | fzf_lua
-- per-picker options (see lua/godoc/pickers/<name>.lua for available fields)
native = {},
telescope = {},
snacks = {},
mini = {},
fzf_lua = {},
},
})See the source for further details:
- Go adapter: lua/godoc/adapters/go.lua
- Pickers: lua/godoc/pickers/
- Types: lua/godoc/types.lua
By default, go doc output is rendered without syntax highlighting. You can opt
in by installing the
tree-sitter-godoc and
tree-sitter-go parsers.
tree-sitter-godoc provides base highlighting and uses injection queries to hand
off Go code regions to tree-sitter-go.
Install nvim-treesitter
using your plugin manager of choice (branch main).
Run this once at startup (for example, in your init.lua):
local godoc_parser = {
install_info = {
url = "https://github.com/fredrikaverpil/tree-sitter-godoc",
files = { "src/parser.c" },
version = "*",
},
filetype = "godoc",
}
require("nvim-treesitter.parsers").godoc = godoc_parser
-- Map godoc filetype to the godoc parser
vim.treesitter.language.register("godoc", "godoc")
-- Re-register after :TSUpdate so the parser survives parser-list reloads
vim.api.nvim_create_autocmd("User", {
pattern = "TSUpdate",
callback = function()
require("nvim-treesitter.parsers").godoc = godoc_parser
end,
})
-- Optional: also use the godoc filetype for `.godoc` files
vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, {
pattern = "*.godoc",
callback = function()
vim.bo.filetype = "godoc"
end,
}):TSInstall go godocOverride the go adapter's get_syntax_info in your setup() call:
require("godoc").setup({
adapters = {
{
name = "go",
opts = {
get_syntax_info = function()
return {
filetype = "godoc",
language = "godoc",
}
end,
},
},
},
})godoc.nvim is extensible via adapters. Three flavors are supported:
- Built-in — shipped in lua/godoc/adapters/. Only
gotoday. - User-defined — written inline in your own config.
- Third-party — installed as a separate plugin that exposes a
setup()function returning aGoDocAdapter.
You can override any adapter's options (including the command name) via opts.
require("godoc").setup({
adapters = {
-- Built-in, default options
{ name = "go" },
-- Built-in with user override (rename command)
{ name = "go", opts = { command = "GoDocs" } },
-- User-defined (no `name` field)
{
command = "MyDoc",
get_items = function()
return vim.fn.systemlist("mylang doc --list")
end,
get_content = function(choice)
return vim.fn.systemlist("mylang doc " .. choice)
end,
get_syntax_info = function()
return { filetype = "mydoc", language = "mylang" }
end,
goto_definition = function() end,
},
-- User-defined, purely for fun
{
command = "DadJokes",
get_items = function()
return { "coffee", "pasta" }
end,
get_content = function(choice)
local db = {
coffee = { "What did the coffee report to the police?", "A mugging!" },
pasta = { "What do you call a fake noodle?", "An impasta!" },
}
return db[choice]
end,
get_syntax_info = function()
return { filetype = "text", language = "text" }
end,
goto_definition = function() end,
},
-- Third-party
{
setup = function()
return require("pydoc.nvim").setup({ --[[ third-party opts ]] })
end,
},
-- Third-party with override
{
setup = function()
return require("pydoc.nvim").setup({ --[[ third-party opts ]] })
end,
opts = { command = "PyDocs" },
},
},
})Note
pydoc.nvim and mylang above are fictional — illustrative only.
All adapters must implement the GoDocAdapter interface:
--- @class GoDocAdapter
--- @field command string The vim command name to register
--- @field get_items fun(): string[] Function that returns a list of available items
--- @field get_content fun(choice: string): string[] Function that returns the content
--- @field get_syntax_info fun(): GoDocSyntaxInfo Function that returns syntax info
--- @field goto_definition? fun(choice: string, picker_gotodef_fun: fun()?): nil Function that returns the definition location
--- @field health? fun(): GoDocHealthCheck[] Optional health check functionUser overrides use GoDocAdapterOpts:
--- @class GoDocAdapterOpts
--- @field command? string Override the command name
--- @field get_items? fun(): string[] Override the get_items function
--- @field get_content? fun(choice: string): string[] Override the get_content function
--- @field get_syntax_info? fun(): GoDocSyntaxInfo Override the get_syntax_info function
--- @field goto_definition? fun(choice: string, picker_gotodef_fun: fun()?): nil Override the get_definition function
--- @field health? fun(): GoDocHealthCheck[] Override the health check function
--- @field [string] any Other adapter-specific optionsSee lua/godoc/adapters/go.lua for a reference implementation, and lua/godoc/types.lua for the full type definitions.
Pull requests for new built-in adapters or improvements to existing ones are welcome!
:checkhealth godocRuns the health checks associated with every enabled adapter that provides one.
Contributions are very much welcome! ❤️ Please feel free to submit a pull request.
This project uses Pocket for
formatting and linting tasks. Run ./pok to execute all tasks, or ./pok -h to
see available tasks.