-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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: support server-side fuzzy matching #32754
Comments
In our discussion @muirrn suggested that the current default method is such that a lowercase partial pattern implies case insensitive candidate selection. However I don't think I'm seeing this:
Trying to complete Which seems to suggest that candidate selection is case sensitive. |
Sorry @myitcv, I was talking specifically about the un-merged fuzzy matching logic. Currently gopls has no matching logic at all, it is always an exact prefix match. Editors however can fetch all the candidates when you type |
Thanks for clarifying.
This is exactly why I don't think this logic belongs in editors. Because qualified identifier/selector-based completions are only part of the picture. But also because presumably the editors need to keep asking for completion candidates because they can't know when to stop? At which point, Would this not also give us consistency across editors? Apologies if part of the reason we're talking past each other here is a difference between the different editor approaches here. My experience is only Vim. |
I think VSCode works the same for unqualified completions. If you haven't typed anything yet you can manually trigger a completion, or once you type your first character it will fetch the completions and then filter in the editor as you continue typing. Emacs works similarly by default, but LSP completions in Emacs do not currently support fuzzy matching.
VSCode does not refetch candidates as long as you are still typing in the same identifier. Emacs works the same way normally, but currently it refetches candidates after every keystroke to work around a previous bug. But, I think we are in agreement in regards to who should be doing the matching. Server side matching should give a better (faster, more consistent) experience overall. The downside is it pushes the various matching preferences/options from the editor into gopls (i.e. gopls might not support the matching/completion options you are used to in your editor). If you want to try out server side fuzzy matching (as well as deep completions) you can use this branch https://github.com/muirrn/tools/tree/lsp-fuzzy (just rebased on master). Then if you complete something like "conBack" it will complete to "context.Background()" (assuming "context" is already imported). This also works for "deep" completing into structs, so if you have some struct "foo" and you want to access "foo.bar.baz.qux" you can directly type "qux" and complete and it will expand to "foo.bar.baz.qux". |
Yes, indeed.
I think it forces the editor (plugin) to map between the two, yes, and tie the two together from the user's perspective. But I don't see that as a problem: editor (plugins) are already having to do this sort of mapping in any case with LSP concepts. And it should be relatively easy to add additional strategies to the
I'm very keen to give this a try and see how my brain maps to it! Will try and find some time to do so. Thanks again for your work experimenting with this. |
I agree that we definitely need fuzzy matching on the server side in |
There are other editors out there 😉 This was exactly my point above. If, for any given editor, we find a gap/difference in the strategy expected, we can fill that with an alternate implementation within I don't think we can try and cover all bases for all editors with a single default. |
Sorry, I totally phrased that incorrectly. I said VSCode specifically because it's the only editor I knew about that does the fuzzy matching. There is also a way to force the client to use |
Change https://golang.org/cl/184441 mentions this issue: |
This change uses a fuzzy matching library to score completion results. Updates golang/go#32754 Change-Id: Ia7771b33534de393a865443e05c0fcbf1e9a969b Reviewed-on: https://go-review.googlesource.com/c/tools/+/184441 Run-TryBot: Rebecca Stambler <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Cottrell <[email protected]>
This change uses a fuzzy matching library to score completion results. Updates golang/go#32754 Change-Id: Ia7771b33534de393a865443e05c0fcbf1e9a969b Reviewed-on: https://go-review.googlesource.com/c/tools/+/184441 Run-TryBot: Rebecca Stambler <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Cottrell <[email protected]>
@muirrn - the work in https://go-review.googlesource.com/c/tools/+/190099 looks great. Is it worth leaving this issue open pending making the option for fuzzy matching independent of deep completions? |
Oops, forgot to tag this issue. I think we should keep this open until fuzzy matching is "released" (i.e. enabled by default, perhaps with a config flag to disable). On that note, I've been assuming that everyone wants fuzzy matching, but that sounds like a silly assumption. We need to gather feedback on use cases to disable fuzzy matching, and also detailed feedback on sub-optimal results from the fuzzy algorithm. Maybe we can gather that feedback on this issue as well? |
Change https://golang.org/cl/192137 mentions this issue: |
Invert "useDeepCompletions" config flag to "disableDeepCompletion" and separate out "disableFuzzyMatching" which reverts to the previous prefix matching behavior. I separated fuzzy matching tests out to a separate file so they aren't entangled with deep completion tests. In coming up with representative test cases I found a couple issues which I fixed: - We were treating a fuzzy matcher score of 0 as no match, but the matcher returns 0 for candidates that match but have no bonuses. I changed the matcher interface so that a score of 0 counts as a match. For example, this was preventing a pattern of "o" from matching "foo". - When we lower a candidate's score based on its depth, we were subtracting a static multiplier which could result in the score going negative. A negative score messes up future score weighting because multiplying it by a value in the range [0, 1) makes it bigger instead of smaller. Fix by scaling a candidate's score based on its depth rather than subtracting a constant factor. Updates golang/go#32754 Change-Id: Ie6f9111f1696b0d067d08f7eed7b0a338ad9cd67 Reviewed-on: https://go-review.googlesource.com/c/tools/+/192137 Run-TryBot: Rebecca Stambler <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Rebecca Stambler <[email protected]>
@myitcv can you kindly try out fuzzy matching on master and see if you think it satisfies this issue? |
@muirrn - the options for disabling deep completions and fuzzy matching appear to work, thank you. For now, deep completions and fuzzy matching are enabled by default for I've just raised govim/govim#490 to investigate adding support in If you are happy that server-side fuzzy matching is working, then please do close this issue :) Thanks for working on this! |
Thanks for testing it out!
I think this issue can be closed now, but I don't have the power to do it myself :) |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Raising this following a conversation with @muirrn and @ianthehat
There are a variety of approaches to deciding what completion candidates to offer:
We ultimately, however, need a way for users to configure which method they want.
Whilst there will likely be necessary discussion on what is the most sensible default, this issue is a request to make the option configurable.
The same option could also define the behaviour of functions like #32749, for example
cc @stamblerre @ianthehat
The text was updated successfully, but these errors were encountered: