Skip to content

fredrikaverpil/godoc.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

87 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

godoc

godoc.nvim

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).

Screenshots

Snacks picker Screenshot is showing the Snacks picker.

Telescope picker

Telescope picker

Native picker

Native picker

Features

  • Search and browse docs for Go standard library packages and project packages
  • Go to definition from picker
  • Optionally leverage stdsym for symbol search
  • Optional syntax highlighting via tree-sitter
  • Supports pickers:
  • Extend to other languages and data sources via adapters

Requirements

  • Neovim >= 0.8.0 (>= 0.12 if installing via vim.pack)
  • Go installation with go doc and go list commands available

Installation

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()
EOF

Usage

The 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 gd to 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.Builder

Warning

: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).

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:

Syntax highlighting via tree-sitter

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.

1. Install nvim-treesitter

Install nvim-treesitter using your plugin manager of choice (branch main).

2. Register the godoc parser

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,
})

3. Install the parsers

:TSInstall go godoc

4. Tell godoc.nvim to use the godoc parser

Override 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,
      },
    },
  },
})

Adapters

godoc.nvim is extensible via adapters. Three flavors are supported:

  • Built-in — shipped in lua/godoc/adapters/. Only go today.
  • User-defined — written inline in your own config.
  • Third-party — installed as a separate plugin that exposes a setup() function returning a GoDocAdapter.

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.

Adapter interface

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 function

User 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 options

See 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!

Health Check

:checkhealth godoc

Runs the health checks associated with every enabled adapter that provides one.

Contributing

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.

About

Fuzzy search Go packages/symbols and view docs from within Neovim

Topics

Resources

License

Stars

Watchers

Forks

Contributors