Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/tools/gopls: suggested completions include many irrelevant, non-deterministic entries #43374

Open
cespare opened this issue Dec 25, 2020 · 4 comments

Comments

@cespare
Copy link
Contributor

@cespare cespare commented Dec 25, 2020

What version of Go are you using (go version)?

$ go version
go version go1.15.6 linux/amd64

Does this issue reproduce with the latest release?

Yes, and with the current tip of gopls as well.

What operating system and processor architecture are you using (go env)?

linux/amd64

What did you do?

I can reproduce this with basically any code.

But concretely, I used this single-file package:

package main

func f(int) {}

func x() {
	n := 3
	m := 4
	f(|)
}

The | is where my cursor is when I invoked autocompletion.

What did you expect to see?

I expected to see completions that make sense given the types involved. Whatever the completions I saw, I expected that if I invoked autocompletion a second time without making any change whatsoever, I should see the same list of suggestions again.

What did you see instead?

I saw a long list with many irrelevant suggestions. Additionally, every time I invoked autocompletion, the list was different.

I noticed this in my usual environment (vim + govim) but I can reproduce with vscode as well. Here are some screenshots (I pressed ctrl-space three times in a row and got these three results):

screen_20201224235014

screen_20201224235025

screen_20201224235033

@myitcv
Copy link
Member

@myitcv myitcv commented Jan 22, 2021

Drive-by guess: candidates have an equal score and there is no ordering defined across them, hence the seemingly "random" behaviour.

FWIW I've also struggled with the verbose nature of deep completions (which is why you see the crypto.BLAKE* candidates above, I believe). The unfortunate thing is that in certain situations they would be incredibly useful - but the noise in the 90% of cases is what makes them unusable for me. It feels like this is the very nature of the beast - i.e. there isn't a way to turn down the noise and keep the useful cases alive. But I could very well be totally wrong on that.

@muirdm
Copy link

@muirdm muirdm commented Feb 5, 2021

I believe they change as more unimported packages are processed in the background. Do they not stabilize eventually?

Basic objects (e.g. ints, strings) from unimported packages are probably very rarely selected as completion candidates, so maybe we can completely omit them. Or perhaps have a minimum prefix requirement before they show up.

Or even better maybe we could go down to showing a single deep completion candidate (instead of three), and only show it if it is the top scoring candidate.

@gopherbot
Copy link

@gopherbot gopherbot commented Apr 17, 2021

Change https://golang.org/cl/311069 mentions this issue: lsp/completion: omit deep completions into unimported packages

@muirdm
Copy link

@muirdm muirdm commented Apr 17, 2021

If interested, please try out https://go-review.googlesource.com/c/tools/+/311070/1 . I'm going to use it for a bit and see if there are any places it doesn't offer a completion I expect.

gopherbot pushed a commit to golang/tools that referenced this issue Apr 20, 2021
Don't offer deep completions when completing the name of unimported
packages.

For example:

    var _ int = <>

Completing at <> previously would offer an eclectic array of
candidates such as "bits.LeadingZeros()", "time.Now().Day()", or
"zlib.BestCompression", depending on your luck. These candidates stem
from unimported packages candidates such as "bits" which we continue
searching into for deep candidates.

There are two main reasons these deep completions are not useful:
1. They are not dependable. Not all unimported packages are even
   searched (it stops as soon as it finds a set number).
2. Fuzzy matching does not work (e.g. typing "bilz" will not filter to
   "bits.LeadingZeros" as it does in other cases).

2) could be remedied, but there are so many unimported
package members that I'm not sure it is possible to reduce false
positive deep completions to a satisfactory level.

I also made a couple relevant minor tweaks:
- Fallback sort the unimported packages by path to keep a consistent
  order.
- Don't offer unimported packages at all if there is no prefix.

Updates golang/go#43374.

Change-Id: I9fbcde34a3a9e7781568515bddab9da2fc931139
Reviewed-on: https://go-review.googlesource.com/c/tools/+/311069
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Trust: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants