Closed stubailo closed 7 years ago
This is hard!
Consider these two cases:
query {
field1: field
field2: field
}
schema {
query: QueryType
mutation: MutationType
}
In the first case, it's a query, followed by selections, and each selection has an alias. In the second case, it's a schema definition, followed by field definitions.
As far as I can tell, atom grammars (like textmate grammars before them) don't have any mechanism for "followed by this named pattern". You can define a bunch of small patterns, then hope they come together, but I can't say, like /schema\s+\\{<%= fieldDefinitions %>\\}/
, because you can't insert a named entity like that.
Selections have to be part of the root level grammar to support unnamed queries, eg
{ field1, field2 }
But then they conflict with field definitions!
I'll poke and prod some more, but as far as I can tell, the only way to disambiguate would be to hardcode the entire regular expression, using copy-and-paste for reused elements like directives. Yuck!
I'll probably try again another day, and if it doesnt work, I'll investigate options for generating the .cson
file
Arg!!!!
@rmosolgo Could we maybe separate the current rule into #operationDefinitions
repository and have a separate repository for #schemaDefinition
? Something like this:
{
'name': 'meta.operation'
'comment': 'an operation definition'
'match': '(query|mutation|subscription)\\s*([_A-Za-z][_0-9A-Za-z]*)'
'captures':
'1':
'name': 'storage.type'
'2':
'name': 'variable.other'
'patterns': [
'include' : '#operations'
]
},
{
'name': 'meta.operation'
'comment': 'a schema definition'
'match': '(schema)\\s*([_A-Za-z][_0-9A-Za-z]*)'
'captures':
'1':
'name': 'storage.type'
'2':
'name': 'variable.other'
'patterns': [
'include' : '#schemaDefinitions'
]
}
I considered something like that, but gave up before trying :S
My understanding of include
(taken solely from https://manual.macromates.com/en/language_grammars) is that it can be used two places:
begin
and end
I tried to imagine what would be required for a begin
and end
and that's where I gave up. The logical begin
& end
is { ... }
, but of course, that's not specific enough, that's the whole problem! To actually code the begin & end, I'm afraid you'd have to hardcode the whole "header" (eg, extend type X implements Y, Z
, input B @whateverDirective(arg: "str")
) with opening {
as "begin", then "end" would be just }
.
Since there's no (not that i could find) recipe for reusing a pattern inside another pattern, you'd have to hardcode literals again (for directive arguments).
Another issue I had, although I only tried for a couple minutes, was capturing elements from a repeating pattern (specifically {typename}, {typename}, {typename}
). The goal is to highlight the typenames but not the commas. I ended up coding it like (([_A-Za-z][_A-Za-z0-9]+),?\\s*)*
, so the outer capture is used only for repetition, then I somehow need to get the inner captures to highlight them. Yikes!
I became aware via a duplicate package that language-babel
has GraphQL highlighting. Judging by the previews, it has fewer and different bugs, so as soon as I can, I will review that one and see if I can learn any tricks from it!
0.8.0 includes a copy-paste of graphql highlighting from language-babel.
It has much better support for schema language. Please reopen another issue if you find a specific bug!
I think READMEs will often want to describe their schema in GraphQL form, like so:
As you can see, comments and arguments are highlighted but not other stuff. It would be cool to highlight for example the
type
keyword, the types, etc.