Skip to content

x/tools/gopls: Completion: show documentation for unimported candidates too #79820

Description

@ab7z

gopls version

golang.org/x/tools/gopls v0.22.0 (built with go1.26.4, darwin/arm64).

go env

go version go1.26.4 darwin/arm64.

What did you do?

In a file that does not yet import os, type an unimported-package reference and trigger completion:

package main

func main() {
	os.Exit
}

Observed the editor's documentation popover for the highlighted Exit candidate. The client is Zed 1.5.3, but the behavior is independent of the client (see below).

What did you expect to see?

The documentation popover showing os.Exit's doc comment — the same documentation that appears once os is imported.

What did you see instead?

The completion candidates are offered correctly (with additionalTextEdits to add the import), but no documentation is available for any unimported candidate. Documentation only appears after the package is actually imported.

Inspecting the LSP traffic shows this is server-side:

  1. Completion items for unimported packages carry no documentation. Every item in the textDocument/completion responses contains only label, kind, detail (e.g. "func (from \"os\")"), textEdit, and additionalTextEdits. There is no documentation field, and no data field. Representative item:

    {
      "label": "Exit",
      "kind": 3,
      "detail": "func (from \"os\")",
      "sortText": "00000",
      "filterText": "Exit",
      "insertTextFormat": 2,
      "textEdit": { "newText": "Exit(${1:code int})", "insert": { "...": "..." } },
      "additionalTextEdits": [
        { "range": { "...": "..." }, "newText": "\nimport \"os\"\n" }
      ]
    }

    By contrast, once the package is imported the same candidates do include documentation, so this is specific to the unimported (index-sourced) path.

  2. gopls advertises no completion resolve capability. The initialize response sets:

    CompletionProvider: &protocol.CompletionOptions{
        TriggerCharacters: []string{"."},
    },

    i.e. completionProvider.resolveProvider is unset/false. So there is no completionItem/resolve path for a client to lazily fetch the documentation that was omitted — and indeed no client request can recover it.

The combined effect is that documentation is simply unavailable for unimported completion candidates, in any LSP client: it is neither embedded in the completion item nor obtainable via completionItem/resolve.

Request

Provide documentation for unimported completion candidates, via either:

  • computing the doc comment inline for the offered candidates (within the completion budget), or
  • advertising completionProvider.resolveProvider: true and implementing completionItem/resolve so the doc comment can be fetched lazily when a candidate is selected.

The candidate's package is already known at completion time (it is encoded in detail and in the additionalTextEdits import), so the symbol's documentation should be obtainable on demand.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FeatureRequestIssues asking for a new feature that does not need a proposal.ToolsThis label describes issues relating to any tools in the x/tools repository.goplsIssues related to the Go language server, gopls.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions