rmosolgo / language-graphql

GraphQL support for Atom text editor
MIT License
57 stars 13 forks source link

Highlight type definition language #3

Closed stubailo closed 7 years ago

stubailo commented 8 years ago

I think READMEs will often want to describe their schema in GraphQL form, like so:

type Comment {
  postedBy: User!
  createdAt: String! # Actually a date
  content: String!
}

type Entry {
  repository: Repository!
  postedBy: User!
  createdAt: String! # Actually a date
  score: Int!
  comments: [Comment]! # Should this be paginated?
  commentCount: Int!
}

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.

rmosolgo commented 8 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

rmosolgo commented 8 years ago

Arg!!!!

image

asiandrummer commented 8 years ago

@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'
  ]
}
rmosolgo commented 8 years ago

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:

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!

rmosolgo commented 8 years ago

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!

rmosolgo commented 7 years ago

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!