-
Notifications
You must be signed in to change notification settings - Fork 1.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
Feature: LSP Fragment completions #4134
Feature: LSP Fragment completions #4134
Conversation
@@ -710,6 +753,7 @@ fn resolve_completion_items_for_inline_fragment_type( | |||
type_: Type, | |||
schema: &SDLSchema, | |||
existing_inline_fragment: bool, | |||
include_fragment: bool, |
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.
nit: boolean arguments maybe confusing sometimes.
Maybe we should change this into the callback -> format_fragment_completion_label
?
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 completely agree about boolean arguments, I rewrote with a callback and it seemed more confusing
We already use a boolean argument in a similar situation for resolve_completion_items_for_fragment_spread
. Here existing_fragment_spread: bool
is used to describe whether the completion is being used to rename an existing spread.
I've renamed this function and argument for inline fragments to more closely align to the existing one for fragment spreads. Now the argument is existing_fragment_spread
.
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 is super cool!
Thank you for working on this, just one small comment on the boolean argument, but overall looks great.
I don't think we need this, I think we automatically inline these fragments anyways, so they are redundant.
I think it should be fine. As long as you can refine the list of suggestions base on what you've already typed. Can you? Will it filter out irrelevant fragment spreads?
Hmm, seems like it should be fine. |
Awesome, thanks for looking at this so quickly @alunyov! :D
Cool, I can make a small change to filter out the base type for fragment Test on MyInterfaceType {
|
# Completions:
# ...on MyInterfaceType <-- Remove this one
# ...on ConcreteType
}
This is the behaviour while typing - so long as it exactly matches the completion label then it persists, but if you close the completion window & reopen it, then you don't get any completions (*except for when you're writing a fragment spread, i.e., This logic could definitely be improved, but it would mean adjusting the AST to allow inline fragments with no identifiers, i.e., allowing Screen.Recording.2022-11-21.at.19.06.04.mov |
…g_fragment_spread`
@alunyov I've made some changes to clean up the arguments a little, and in the process explored how completion works for existing inline fragments. I added more tests to document this & fixed the behaviour in my change. There is still plenty of weirdness in {
...on StartOfFragmentNam|
# ^ Completions
# - ...on StartOfFragmentName
# - ...on StartOfFragmentNameOther
}
Also I checked this out again, and at the moment this MR behaves the same way as GraphiQL, so I'm tempted to keep it as is. Let me know if you'd like anything else changed 😄 |
@alunyov has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
Thank you @beaumontjonathan for working on this. This looks great! I'll test this internally, and I think we can ship this. A few ideas on how we can improve this further (but maybe as a follow-up PRs);
|
This is reasonable, and definitely the desired behaviour. I looked into this initially, but it would require a change to the parser - at the moment we won't recognize that it's a fragment unless if has a identifier after the It's definitely possible to fix this, but would have a larger blast radius & I think it could come later.
^ This is really interesting. For editor completions, I think if we get the above working, then we should get this for free from the editor. This is the current behaviour for field completions in VSCode Screen.Recording.2022-11-22.at.21.35.43.mov |
@alunyov has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
Oh, one valid case that we need to fix here. We should not add We have a validation that prevents from adding these fields: relay/compiler/crates/relay-transforms/src/validations/disallow_typename_on_root.rs Lines 45 to 47 in 15cc327
So we should not add this to the autocomplete list for these types. |
@alunyov has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
@alunyov has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
Summary: # LSP Fragment Completions Adds support for `__typename`, fragment, and inline fragment completions for `interface`/`union`/`type`. Completions are ordered using [`sortText`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion), with the following `precedence`: 1. Fields on the type, e.g., fields from `type`/`interface` 2. `__typename` 3. `...on T` inline fragments 4. `...F` fragments The modified tests show the behaviour, but a summary here is: ## `interface` - `__typename: String!` completion - `...on T` completions for the `interface` type itself and all types which implement it - `...F` completions for all fragments `F` on the `interface` or any `implements`' of it ### Example <img width="468" alt="Screenshot 2022-11-21 at 13 59 39" src="https://user-images.githubusercontent.com/17055343/203078448-465eb2ab-6165-49ee-9f9d-403bcbe6f739.png"> ## `union` - `__typename: String!` completion - `...on T` completions for the `union` type itself and for each variant - `...F` completions for all fragments `F` on the `union` or any variants of it ### Example <img width="471" alt="Screenshot 2022-11-21 at 13 59 56" src="https://user-images.githubusercontent.com/17055343/203078444-9f98c439-facb-4c5d-ab0b-ccf552fca0e2.png"> ## `type` - `__typename: String!` completion - `...F` completions for all fragments `F` on the `type` or on any `interface`s or `union`s it implements ### Example <img width="469" alt="Screenshot 2022-11-21 at 14 00 10" src="https://user-images.githubusercontent.com/17055343/203078437-10b43e4d-152c-4592-a7e9-2bfad020cde4.png"> ## Questions: - [x] Does Relay have a preferred style for spacing of fragments? Which should be used on these completions? Should this be a user configurable option? - `...on T` vs `... on T` - `...F` vs `... F` - [x] Should inline fragment completions exist for the type itself? E.g., when fragmenting on a `type User`, should `...on User` be suggested? - At the moment this MR adds this for `interface` & `union` but not `type` - should this be consistent? - [x] Will this feature be annoying for users of the LSP in orgs with a large codebase & lots of fragments? Should either of these be user configurable? - [x] Is the `sortText` robust enough? This has been implemented by prefixing a number to the start of the `label`; it seems to work for me locally ([code](https://github.com/facebook/relay/pull/4134/files#diff-04b7155ac238238b6434c2f32c30439229c0127075572f2d2f7519b574ff90c6R1018)) Pull Request resolved: facebook#4134 Reviewed By: tyao1 Differential Revision: D41470372 Pulled By: alunyov fbshipit-source-id: ef04a34fb7e145cb9884c8b79345fd8e0a26cf83
Summary: # LSP Fragment Completions Adds support for `__typename`, fragment, and inline fragment completions for `interface`/`union`/`type`. Completions are ordered using [`sortText`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion), with the following `precedence`: 1. Fields on the type, e.g., fields from `type`/`interface` 2. `__typename` 3. `...on T` inline fragments 4. `...F` fragments The modified tests show the behaviour, but a summary here is: ## `interface` - `__typename: String!` completion - `...on T` completions for the `interface` type itself and all types which implement it - `...F` completions for all fragments `F` on the `interface` or any `implements`' of it ### Example <img width="468" alt="Screenshot 2022-11-21 at 13 59 39" src="https://user-images.githubusercontent.com/17055343/203078448-465eb2ab-6165-49ee-9f9d-403bcbe6f739.png"> ## `union` - `__typename: String!` completion - `...on T` completions for the `union` type itself and for each variant - `...F` completions for all fragments `F` on the `union` or any variants of it ### Example <img width="471" alt="Screenshot 2022-11-21 at 13 59 56" src="https://user-images.githubusercontent.com/17055343/203078444-9f98c439-facb-4c5d-ab0b-ccf552fca0e2.png"> ## `type` - `__typename: String!` completion - `...F` completions for all fragments `F` on the `type` or on any `interface`s or `union`s it implements ### Example <img width="469" alt="Screenshot 2022-11-21 at 14 00 10" src="https://user-images.githubusercontent.com/17055343/203078437-10b43e4d-152c-4592-a7e9-2bfad020cde4.png"> ## Questions: - [x] Does Relay have a preferred style for spacing of fragments? Which should be used on these completions? Should this be a user configurable option? - `...on T` vs `... on T` - `...F` vs `... F` - [x] Should inline fragment completions exist for the type itself? E.g., when fragmenting on a `type User`, should `...on User` be suggested? - At the moment this MR adds this for `interface` & `union` but not `type` - should this be consistent? - [x] Will this feature be annoying for users of the LSP in orgs with a large codebase & lots of fragments? Should either of these be user configurable? - [x] Is the `sortText` robust enough? This has been implemented by prefixing a number to the start of the `label`; it seems to work for me locally ([code](https://github.com/facebook/relay/pull/4134/files#diff-04b7155ac238238b6434c2f32c30439229c0127075572f2d2f7519b574ff90c6R1018)) Pull Request resolved: facebook#4134 Reviewed By: tyao1 Differential Revision: D41470372 Pulled By: alunyov fbshipit-source-id: ef04a34fb7e145cb9884c8b79345fd8e0a26cf83
LSP Fragment Completions
Adds support for
__typename
, fragment, and inline fragment completions forinterface
/union
/type
.Completions are ordered using
sortText
, with the followingprecedence
:type
/interface
__typename
...on T
inline fragments...F
fragmentsThe modified tests show the behaviour, but a summary here is:
interface
__typename: String!
completion...on T
completions for theinterface
type itself and all types which implement it...F
completions for all fragmentsF
on theinterface
or anyimplements
' of itExample
union
__typename: String!
completion...on T
completions for theunion
type itself and for each variant...F
completions for all fragmentsF
on theunion
or any variants of itExample
type
__typename: String!
completion...F
completions for all fragmentsF
on thetype
or on anyinterface
s orunion
s it implementsExample
Questions:
...on T
vs... on T
...F
vs... F
type User
, should...on User
be suggested?interface
&union
but nottype
- should this be consistent?sortText
robust enough? This has been implemented by prefixing a number to the start of thelabel
; it seems to work for me locally (code)