-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
WIP: feat: field and value def autocomplete #1758
base: main
Are you sure you want to change the base?
Conversation
{ label: '__DirectiveLocation' }, | ||
{ label: '__TypeKind' }, | ||
{ label: 'Episode' }, | ||
{ label: 'InputType' }, |
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 probably an existing bug, as the InputType
should probably not appear here
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.
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.
Thanks! But I don't seem to understand the role of field name here.
In my current thinking, since state.prevState.type
(type Book) is a GraphQLObjectType, and InputType
is a GraphQLInputObjectType, so it should not appear in the hintList.
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.
my bad, misunderstood you before. i understand this bug better now. i’ll circle back after some sleep
Codecov Report
@@ Coverage Diff @@
## main #1758 +/- ##
==========================================
+ Coverage 65.70% 65.90% +0.19%
==========================================
Files 85 86 +1
Lines 5106 5144 +38
Branches 1631 1640 +9
==========================================
+ Hits 3355 3390 +35
- Misses 1747 1750 +3
Partials 4 4
Continue to review full report at Codecov.
|
@@ -246,6 +248,16 @@ export function getAutocompleteSuggestions( | |||
return getSuggestionsForVariableDefinition(token, schema, kind); | |||
} | |||
|
|||
// Input value definition | |||
if (kind === RuleKinds.INPUT_VALUE_DEF && step === 2) { |
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'm not particularly sure what step means here, but I just found it to be representative of the current state. Hope to get some advice :)
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.
yep, that's it! it represents the step in the parser rule you're at. some parser Rules have only one step, others have two.
here's where the magic happens in parser:
this is probably the most straightforward implementation example. with ARGUMENT, step 1 is when we want argument name, and step 2 is when we want an input value.
graphiql/packages/graphql-language-service-interface/src/getAutocompleteSuggestions.ts
Line 161 in c4cba85
// Input values: Enum and Boolean |
so, if i wanted to implement autocompletion for field names for object types that extended interfaces, i would do that on OBJECT_TYPE
step 1.
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.
oh and i guess you found one that has three steps! :D
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.
Just thinking aloud.. is it possible for the steps to have constants for referencing them? In order to give the steps meaning beyond just 2
for example? 🤔
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.
good question! they have a different meaning in the context of each rule. we could have Step.First
but that wouldn't be much more readable, or would it?
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.
Not really, it would pretty much be the same thing 😄 I'll think about it a bit more.
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.
we could also specify enums for each rule that has multiple steps that are referenced, such as ObjectTypeSteps.Name = 1
and ObjectTypeSteps.Field = 2
, and then FragmentDefintionSteps.Name = 1
, etc
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.
Maybe that would make sense, since the meaning of each step is defined by the GraphQL type being worked on. My only concern is that, since the values overlap, there might be an issue where they are mixed up. Typescript wouldn't complain since they are all numbers (except they are typed with the right enum type 🤔 ) but the behavior wouldn't be the expected behavior.
For example, InputObjectTypeSteps.Field
might be equal to RuleKindStep.Name
. Maybe my concern is a non-issue though. Perhaps if there is a way to type guard step
to one of the enums, that would make step
have just one meaning and remove ambiguity.
awesome work so far! really appreciate your help as always. works great for me with object type fields and input type fields. would you like me to look into a way to make it so that the autocomplete can begin a space after the |
Sure, that's what I want too. I noticed that in the typescript file, when I type ... interface Author {
name: string;
}
interface Book {
author: ...
} I don't get an active suggestion after I type The difference is that when I type the first letter here, like I think it would be nice to have a similar logic here. |
@stonexer that's so odd, because it works in graphiql and monaco-graphql: when you say a typescript file, are you referring to vscode-graphql? |
@acao Haha,it's not a bug here. Actually I mean the experience of using monaco to edit typescript files. |
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.
LGTM. Only concern I see would be the dropped test coverage. @acao is there a requirement for PRs not to reduce the test coverage?
@imolorhe that is definitely something to consider! I disabled that once because a PR dropped coverage because of a refactor (I deleted so much redundant code with good coverage that it caused overall coverage to go down). I evaluate it on a case-by-case basis as a maintainer, but for this PR I think we should have additive coverage, though we're adding three cases. I don't think this PR is ready myself because of the issue with spaces @stonexer and I discussed in discord, unfortunately we didn't surface that discussion here so let me summarize: desired behavior for this PR: autocompletion for variables should be triggered on current behavior in this PR: |
Okay got it. Will un-approve and wait for that fix then 😄 |
Are there other situations where we need |
good question! we can experiment with that |
Tried it, I think it's not bad |
this adjustment looks better for monaco editor, but it still doesn't fix the issue on the codemirror side. i wonder why? gonna keep looking into this! |
4fa9ca3
to
1c11938
Compare
so sad i didn't merge this sooner! this is incredible |
@stonexer this is sooo close - maybe we can configure |
@dwwoelfel this is another good place for the tokenizer |
|
fef0417
to
dc65988
Compare
@acao I'm back haha :), sorry for disappearing for a long time before for personal reasons. I added |
@stonexer so glad you are back! any help you can provide is always appreciated, no worries! definitely can review again soon, yes! |
Currently, the graphql Referrence #888 (comment), I did some experimentations on graphql schema(sdl) editor. I made a dumb parser with chevrotain(a powerful tool), and just implemented a little bit of language service (adding support for type name and inputType name completion). Here's the demo and the source code. Maybe someday we can implement this in a better way. 😃 |
I will check this out locally and see how it’s working! This is such a valuable feature |
@stonexer note to test with the monaco graphql mode, just run |
@stonexer I'd love to revive this effort soon! it's so close! |
@stonexer I've been looking at chevrotain's grammar for graphql since last year, and it's enticing. Incredibly fault tolerant. I think it's worth looking at replacing the language parser with this entirely moving forward. It would mean re-writing autocomplete and hover entirely, but it would be worth it |
New Functionality
This PR introduces "show all completion values" for an empty input for input types and object types. Before this, completion only appeared on the first typed character.
Once a user types
fieldName: ▍
they should see all available values, including custom scalars defined in the schema, input types and inline defined input typesTesting
Check out either the graphiql 1 or monaco examples below, and try some basic SDL cases to explore the new functionality in the above features.