go icon indicating copy to clipboard operation
go copied to clipboard

x/tools/gopls: auto-completion not listing values from unimported packages

Open dppascual opened this issue 2 years ago • 4 comments

gopls version

golang.org/x/tools/gopls v0.11.0
    golang.org/x/tools/[email protected] h1:/nvKHdTtePQmrv9XN3gIUN9MOdUrKzO/dcqgbG6x8EY=

go env

GO111MODULE="on"
GOARCH="amd64"
GOBIN="/Users/dppascual/go/bin"
GOCACHE="/Users/dppascual/Library/Caches/go-build"
GOENV="/Users/dppascual/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/dppascual/go/pkg/mod"
GONOPROXY="*.bbva.com,*.igrupobbva"
GONOSUMDB="*.bbva.com,*.igrupobbva"
GOOS="darwin"
GOPATH="/Users/dppascual/go"
GOPRIVATE="*.bbva.com,*.igrupobbva"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.19"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/zg/tz2xtl3138bfl888yv2gc_600000gn/T/go-build3334315292=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Support for autocompletion of unimported packages was introduced in this ticket https://github.com/golang/go/issues/31906, but it seems not working, not sure if this feature has been deprecated. When you create a new package and import a value from such package in another one placed in the same workspace, no member is shown in the completions suggestions pop up. Attached a video as an example:

https://user-images.githubusercontent.com/10468373/213738593-5a39162e-ac8d-4b26-bb1f-9c60843f229e.mov

What did you expect to see?

A list of candidates from unimported packages.

What did you see instead?

No candidates at all until I manually import a package.

Editor and settings

Editor:

 nvim --version
NVIM v0.8.2
Build type: Release
LuaJIT 2.1.0-beta3
Compiled by brew@Monterey

Features: +acl +iconv +tui
See ":help feature-compile"

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/usr/local/Cellar/neovim/0.8.2/share/nvim"

Run :checkhealth for more info

Gopls settings:

  gopls = {
    gopls = {
      -- buildFlags = { "-tags=debug" },
      -- ["local"] = "github.com/sourcegraph/sourcegraph",
      analyses = {
        unusedparams = true,
      },
      staticcheck = true,
      experimentalPostfixCompletions = true,
      hints = {
        parameterNames = true,
        assignVariableTypes = true,
        constantValues = true,
        rangeVariableTypes = true,
        compositeLiteralTypes = true,
        compositeLiteralFields = true,
        functionTypeParameters = true,
      },
    },
  },

dppascual avatar Jan 20 '23 16:01 dppascual

Hi @dppascual, thank you for the report.

I think I know what this is. The unimported completion cache is built asynchronously in the background. If you added the v1 package recently, it will not show up in unimported completion.

If you restart gopls, you should get unimported completion for this package. Can you confirm?

Assuming that works, there is still a UX problem here: gopls knows that metadata has been invalidated, and so should invalidate the unimported completion cache eagerly.

findleyr avatar Jan 26 '23 14:01 findleyr

Hi @findleyr, thanks for your reply. I've just created a new package and after gopls is restarted, values from the recently created package are shown as candidates in the completions suggestions pop up.

On the other hand, if I start typing the name of any exported value (function, type, ...) with no package name explicitly indicated as a prefix; gopls only reports suggestions from imported packages or std library packages. It seems that if we want completion suggestions from unimported packages, gopls forces us to

  • Import explicitly the package or
  • Typing the name of the package followed by the name of the value.

Do you know if there is any configurable option to tell gopls that I want all packages from my current workspace to be taken into account when an autocompletion operation is performed?

dppascual avatar Jan 30 '23 17:01 dppascual

Thanks for checking @dppascual

Assuming that works, there is still a UX problem here: gopls knows that metadata has been invalidated, and so should invalidate the unimported completion cache eagerly.

Agree that this is a UX bug - users shouldn't require to restart gopls. I marked this issue as NeedsInvestigation, but @findleyr, if you know how to fix this, please relabel it accordingly.

if I start typing the name of any exported value (function, type, ...) with no package name explicitly indicated as a prefix; ; gopls only reports suggestions from imported packages or std library packages ...

I think this needs to be tracked as a separate feature request.

I am not sure if gopls currently suggests std library package's exported functions or types before importing the package or prefixing with the package name. (I tried some and it was never successful). In theory, I see commonality with the workspace symbol search - as long as there is enough completion budget and no other candidates from imported packages is found.

hyangah avatar Feb 01 '23 15:02 hyangah

I am not sure if gopls currently suggests std library package's exported functions or types before importing the package or prefixing with the package name. (I tried some and it was never successful). In theory, I see commonality with the workspace symbol search - as long as there is enough completion budget and no other candidates from imported packages is found.

Hi @hyangah, you are right, gopls does not suggest std library package's exported functions of types if the mentioned package is not imported or prefixed. I didn't realize the package from the std library was already imported when testing.

Thanks for checking @dppascual

I've been continue testing how gopls resolves values from packages recently created and found an unexpected behaviour during autocompletion procedure. Once gopls is restarted, packages recently created are taking account by gopls, but not always the server sends suggestions from such package, even when there is an exact-match.

I attach a video (compressed at 720p because at 1080p was too big) below where you can see better what I explain before. The type Unit from the package metrics is not always suggested by gopls.

https://user-images.githubusercontent.com/10468373/216640055-86fb3e00-e881-4641-85d5-dcf489ed8a19.mov

**Logs from gopls **

tail -f ~/.local/state/nvim/lsp.log | grep -C 3 'textDocument/completion' 

gopls.log

I think this needs to be tracked as a separate feature request.

Created a new issue to be tracked

dppascual avatar Feb 03 '23 15:02 dppascual

Using VSCode with gopls v0.11.0, I confirm the problem reported in this issue. Specifically, I used a new subpackage of golang.org/x/tools and was unable to get struct field completions for fmt.Stringer or objectpath.Encoder. After upgrading to the latest gopls, both completions were offered. So this bug appears now to be fixed.

adonovan avatar May 23 '23 15:05 adonovan