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: autocomplete keywords #34009
Comments
Hi, I am interested in helping with this. |
@sebsebmc: Awesome! A good place to start looking is https://github.com/golang/tools/blob/master/internal/lsp/source/completion.go. Feel free to reach out to me here or on the Gophers Slack if you need help. Some things to consider:
|
I think if we do a good job with 2), we can probably just start with the "stdScore" (assuming they are naturally ordered after lexical completions). My guess is typing "cont<>" and getting some weird fuzzy match instead of "continue" will be a more common annoyance than typing "cont<>" and getting "continue" instead of a lexical candidate. One other thought: most keywords are statements, so we should also limit those to beginning of statements. For example: for {
breakDance := 123
actuate(brea<>) // don't offer "break" completion because it isn't start of statement
} |
I actually just ran into the |
Hi, I've been looking at completions.go already, I'll be sure to reach out with any questions. |
Would it be alright to submit my in-progress changes and then mark it as work-in-progress (is that the purpose of DNR) somehow? |
So currently I have reduced the keywords into roughly 2 categories: those that the parser thinks might be an identifier, and those that it doesn't. I've been focusing on the Currently, the scoring is very rudimentary and there still needs to be some more work on restricting the keywords to beginnings of statements. This is partially being done right now by bailing on keyword suggestion if the path contains certain nodes like: For nodes that aren't being marked as an identifier, the parser is typically marking them as a I plan on submitting a patch for the first case once I have it flushed out a bit more and then based on that we can think about how to handle the second case. (Or if there's a different approach altogether that would be better) |
Not tested, but to detect if we are at the start of a statement I would start by checking if
I assume you are talking about cases like this: package foo
co<> // want to complete to "const". I had a failed CL that might have helped with this case. The CL would replace the leaf BadDecl in |
I'm not sure that the
The problem are nodes like |
Change https://golang.org/cl/196664 mentions this issue: |
Additional work is needed to add support for keywords used in declarations at the file level. Currently any non-comment text results in The keywords that we want to complete here are: Note: I don't believe testing package statements is possible right now because of packagetest not running tests that don't contain a valid package statement. Another issue is that inside of switch/select statements when there is no case or default statement the the parser expects a right brace so when typing the first case/default keyword users will not get completions. |
For *ast.Ident completion requests, this checks the parent node to see if the token begins a statement and then based on the path adds possible keyword completion candidates. The test lists some cases where this approach cannot provide completion candidates. The biggest thing missing is keywords for file level declarations Updates golang/go#34009 Change-Id: I9d9c0c1eb88e362613feca66d0eea6b88705b9b0 Reviewed-on: https://go-review.googlesource.com/c/tools/+/196664 Run-TryBot: Rebecca Stambler <rstambler@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
It seems that keyword completions are not being proposed in some of the expected cases. It will require a bit more investigation to see what's going on, but I just wanted to note that here. |
Change https://golang.org/cl/217500 mentions this issue: |
Add support for var/func/const/type/import keywords at the file scope. I left out "package" because, currently, if you are completing something that means you must already have a package declaration. The main hurdle was that anything other than a decl keyword shows up as an *ast.BadDecl at the file scope. To properly detect the prefix we manually scan for the token containing the position. I also made a couple small drive-by improvements: - Also suggest "goto" and "type" keywords in functions. - Allow completing directly before a comment, e.g. "foo<>//". I needed this for a test that would have been annoying to write otherwise. Updates golang/go#34009. Change-Id: I290e7bdda9e66a16f996cdc291985a54bf375231 Reviewed-on: https://go-review.googlesource.com/c/tools/+/217500 Run-TryBot: Rebecca Stambler <rstambler@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
Change https://golang.org/cl/220503 mentions this issue: |
Change https://golang.org/cl/220504 mentions this issue: |
Change https://golang.org/cl/220580 mentions this issue: |
Change https://golang.org/cl/220579 mentions this issue: |
Offer "struct", "interface", "map", "chan", and "func" keywords when we expect a type. For example "var foo i<>" will offer "interface". Because "struct" and "interface" are more often used when declaring named types, they get a higher score in type declarations. Otherwise, "map", "chan" and "func" get a higher score. I also got rid of the special keyword scoring. Now keywords just use stdScore and highScore. This makes the interplay with other types of candidates more predictable. Keywords are offered in pretty limited contexts, so I don't think they will be annoying. Finally, keyword candidate score is now to be scaled properly based on how well they match the prefix. Previously they weren't penalized for not matching well, so there were probably some situations where keywords were ranked too high. Updates golang/go#34009. Change-Id: I0b659c00a8503cd72da28853dfe54fcb67f734ae Reviewed-on: https://go-review.googlesource.com/c/tools/+/220503 Run-TryBot: Muir Manders <muir@mnd.rs> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
We now offer "range" keyword in the for loop init statement: for i := r<> // offer "range" completion candidate Updates golang/go#34009. Change-Id: I2e4c1db11c37127406c78191681c39b9dd3439f7 Reviewed-on: https://go-review.googlesource.com/c/tools/+/220504 Run-TryBot: Muir Manders <muir@mnd.rs> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Now we properly offer "case" and "default" keyword completion in cases like: switch { <> } First I had to add an AST fix for empty switch statements to move the closing brace down. For example, say the user is completing: switch { ca<> } This gets parsed as: switch { } Even if we manually recover the "ca" token, "<>" is not positioned inside the switch statement anymore, so we don't know to offer "case" and "default" candidates. To work around this, we move the closing brace down one line yielding: switch { } Second I had to add logic to manually extract the completion prefix inside empty switch statements, and finally some logic to offer (only) "case" and "default" candidates in empty switch statements. Updates golang/go#34009. Change-Id: I624f17da1c5e73faf91fe5f69e872d86f1cf5482 Reviewed-on: https://go-review.googlesource.com/c/tools/+/220579 Run-TryBot: Muir Manders <muir@mnd.rs> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Now we no longer offer keyword completions inside "case" statements: select { case fo<>: // don't offer "for" } Updates golang/go#34009. Change-Id: I908eda32af01fd1912fb587ce59efef1798b6741 Reviewed-on: https://go-review.googlesource.com/c/tools/+/220580 Run-TryBot: Muir Manders <muir@mnd.rs> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
@stamblerre do you have any other keyword TODOs or can this be closed? I'm ignoring "package" since that will probably be a can of worms. |
Change https://golang.org/cl/223120 mentions this issue: |
They probably should be ranked even lower than builtins.
The text was updated successfully, but these errors were encountered: