-
Notifications
You must be signed in to change notification settings - Fork 61
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
LSP: Add autocomplete & hover functionality, and jump to target name #68
Conversation
…ther file this only works for symbols that aren't loaded yet, for the ones that are we'd need to do path resolution of the loaded file to check the type of the loaded symbol
Sorry for the delay in looking at this - I was travelling. How much of a problem is the use of kind = Method? What is the impact of that on a client such as VS Code? Just an incorrect icon in the completion list? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, this looks really good. We need to unpick the bazel file path dependency, so suggest you split into two diffs - one doing the collect_symbols and exported changes (those are good to land before we figure out the rest), then we iterate on #51, and then can land this.
Note that https://sapling-scm.com/ lets you do stacked pull requests, which might be useful.
Thanks for going through this @ndmitchell! I'll go through your comments some time this week and a) tidy up the code and b) split out the Bazel specific stuff to a separate PR. In that case the initial PR might have to omit completion of exported symbols from other files altogether, as completing those requires inserting the appropriate Regarding the "method" type, yeah it's just an incorrect icon basically, or e.g. in Neovim it might have the type "method" as text instead of an icon. Not a huge deal obviously. Thanks for the tip about SaplingSCM, I'll take a look at that as well. For the follow-up PR, I might create a new branch based on both this one and #51, thoughts? |
I'm just about to go through #51 (the person who was working from this on our side left Meta, so it accidentally got lost, oops). Let me see. |
For generating a |
That sounds like a good solution, yeah. Probably you want to be able to do the mapping in two directions:
|
…ly contains', not 'overlaps'
@ndmitchell has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
Thanks! I'm going through the code now - plan to split pieces off and land them separately (those obvious bits) and slowly work until there is nothing left. Expect to see pieces of your code trickle out over the next day or so. |
@ndmitchell Awesome, looking forward to it. Feel free to ping me if any questions come up. |
I've submitted all the changes apart from those to lsp/server.rs and a handful of lines to definition.rs. I'll update once they are all landed. For the changes to server:
Overall, looks good, and the automatic adding of load statements is super slick. |
Other notes:
|
# Conflicts: # starlark/src/analysis/exported.rs # starlark/src/codemap.rs
@ndmitchell Nice! I merged in
I don't think so, no. Not sure if the idea is to tackle that via #51 or not? I can try to come up with an initial implementation. One thought I had later on: should that actually be on the
That's a nice idea, I'll try to find some time to add that!
Makes sense. I guess that would be the things under
Added!
Thanks! I was pretty happy with that too :) |
also refactor `completion_options` a bit and extract text edit construction to its own function
… literal for target names NOTE: Unfortunately this has the side effect of having to return a `Span` (unresolved) from the `LspContext`, the hover needs this to extract the string contents from the codemap, to show in the hover popup.
Use the new auto complete type detection to offer different completion options in different scenarios: - Default: Just offer all known local symbols, global symbols, and those that can be loaded from other files. - Parameter: Same, but also offer known parameter names for the current function call. - LoadPath: Offer file system based completions, including files and folders, and if a build system was detected, known repository names. - LoadSymbol: Offer names of symbols exported from the file loaded in the current load statement. - String: Like LoadPath, but also offer files that can't be loaded according to the detected build system, as well as target names, again as detected by the detected build system. - Type: Offer type name completion (very basic at the moment). - None: Don't offer any completions.
By making the args optional, the parser is able to parse an incomplete load statement like this: `load("")` Without this, the LSP is unable to update the AST while this is typed, and as such we can't detect that the cursor is in a load statement, and offer auto complete for the load path.
@ndmitchell OK, so I went off the rails a bit this week 😅 added a bunch of stuff. You can see it from the commits above, but summarizing:
I appreciate that this probably makes reviewing this more complicated, so I'm sorry about that. Is there some (semi-)public channel (Slack, Discord) you have where maybe we can work together a bit more closely to be able to land this? e.g. I know for the Relay team they have a private channel in the GraphQL Discord server. |
@MaartenStaa - might need a VC to ensure we move forward with this. Can you email me at ndmitchell -at- gmail.com and we can figure it out. |
@@ -186,7 +186,7 @@ ExprStmt_: Stmt = <Test> => Stmt::Expression(<>); | |||
LoadStmt: AstStmt = ASTS<LoadStmt_>; | |||
LoadStmt_: Stmt = LoadStmtInner => Stmt::Load(<>); | |||
|
|||
LoadStmtInner: Load = "load" "(" <module:string> <args:("," <LoadStmtSyms>)+> ","? ")" => { | |||
LoadStmtInner: Load = "load" "(" <module:string> <args:("," <LoadStmtSyms>)*> ","? ")" => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this changing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check this commit: 1d745b9
In short, it's because the parser is too strict/not error correcting. If the input doesn't fully parse, then when an autocomplete is triggered, the parsed AST is the latest snapshot that did parse. As a result, if the input line is:
load("|")
Where |
is the cursor, there's no way of knowing that the cursor is inside a load
statement—as it's not syntactically correct.
|
||
/// A hint for which build system to resolve. | ||
#[derive(ValueEnum, Debug, Clone, PartialEq, Eq)] | ||
pub enum BuildSystemHint { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have expected this to go outside this repo - it seems that encoding the possible build systems stops others from using this,
@@ -786,6 +800,30 @@ pub enum DocItem { | |||
Object(DocObject), | |||
Function(DocFunction), | |||
Property(DocProperty), | |||
Param(DocParam), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels like the wrong place to put DocParam.
@@ -30,7 +29,7 @@ impl AstModule { | |||
/// | |||
/// NOTE: If the AST is exposed in the future, this function may be removed and implemented | |||
/// by specific programs instead. | |||
pub fn find_function_call_with_name(&self, name: &str) -> Option<ResolvedSpan> { | |||
pub fn find_function_call_with_name(&self, name: &str) -> Option<Span> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this a useful change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fdaa22b
It's useful because it allows to extract the source code from the codemap, which you can't do with a ResolvedSpan
. So the hover can use the Span
to return the code in which a target is defined.
@ndmitchell has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
I've gone through this PR in consultation with @MaartenStaa:
With that I have 6 diffs that are ready to land now (being reviewed and landed internally) then one diff on top which is the hover/completion stuff. Once the prerequisites land I'll publish that and share it back here (it is 95%+ the work of @MaartenStaa). |
Summary: This is code from facebook#68, with cleanups. Differential Revision: D47208501 fbshipit-source-id: 4baf8714123b08de3e111c8002669ca4d673383a
All the dependencies are now landed. #79 is the code which is basically a version of this. |
Summary: Pull Request resolved: facebook#79 This is code from facebook#68, with cleanups. Differential Revision: D47208501 fbshipit-source-id: bd744e9625f932d5bd6bc26909f360e6441ae0af
Summary: Pull Request resolved: facebook#79 This is code from facebook#68, with cleanups. Differential Revision: D47208501 fbshipit-source-id: 7f06543338246494054e739c6fc2066bbe31941f
Summary: X-link: facebook/starlark-rust#79 This is code from facebook/starlark-rust#68, with cleanups. Reviewed By: stepancheg Differential Revision: D47208501 fbshipit-source-id: 44f6704dc06fb9150be5c2e7326de0df9f13060d
Given #79 is now landed, closing this diff as it is 90% landed. Please open follow up PR for the rest of the pieces. Thanks so much for your improvements! |
Hooray, thank you! I checked with neovim and a simple bazel program to hopefully see if the |
Fixes #52.
This PR adds the capability of sending auto-complete suggestions when in LSP mode. Currently it supports:
load
for exported symbols from another opened fileNot yet handled/open questions:
kind
of previously loaded symbols is not always correct (i.e. it's always aCompletionItemKind::METHOD
at the moment), because I'd need to resolve the file, which it doesn't do at the moment.load
statement doesn't work yet, for the same reason of resolving the path.load
statements is based on Bazel, I don't know what this should look like for Buck and/or Starlark usage outside of these two build systems. This ties in with added bazel workspace lsp support #51, which has been open for a while.load
statements doesn't handle external repository paths yet, this also ties in with added bazel workspace lsp support #51.I'm hoping with some feedback, and maybe a merge of the Bazel PR, we can get this to a mergeable state 🙂 looking forward to hearing your thoughts!