Skip to content

Commit 334224b

Browse files
authored
extend the markdown syntax for graphql (#3490)
* extend the markdown syntax for graphql * more grammar support, add ruby * apply suggestions from vscode discussion
1 parent d5028be commit 334224b

32 files changed

+1253
-604
lines changed

.changeset/clean-spies-sip.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'vscode-graphql': patch
3+
'vscode-graphql-syntax': patch
4+
---
5+
6+
- add ruby syntax support
7+
- add graphql syntax support in markdown codeblocks for js, ts, jsx, tsx, svelte, vue, ruby, rescript, reason, ocaml, php and python
8+
- make textmate injectors more performant and specific, eliminate redundant config
9+
10+
Big thanks to [@RedCMD](https://github.com/RedCMD) and [@aeschli](https://github.com/aeschli) for your help!

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ working-group/
55
packages/codemirror-graphql/src/__tests__/schema-kitchen-sink.graphql
66
CHANGELOG.md
77
**/CHANGELOG.md
8+
packages/vscode-graphql-syntax/tests/__fixtures__/

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ module.exports = {
3030
'changesets/**/*.md',
3131
'**/CHANGELOG.md',
3232
'functions/*',
33+
'packages/vscode-graphql-syntax/tests/__fixtures__/*',
3334
],
3435
overrides: [
3536
{

custom-words.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ typedoc
9494
vite
9595
vitest
9696
vitejs
97+
vsix
9798
wonka
9899
urql
99100
tsup
@@ -228,3 +229,4 @@ unparsable
228229
randomthing
229230
codicon
230231
edcore
232+
tokenizes

packages/vscode-graphql-syntax/README.md

Lines changed: 33 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -4,180 +4,52 @@ Adds full GraphQL syntax highlighting and language support such as bracket
44
matching.
55

66
- Supports `.graphql`/`.gql`/`.graphqls` highlighting
7-
- [Javascript, Typescript & JSX/TSX](#ts) & Vue & Svelte
8-
- ReasonML/ReScript (`%graphql()` )
9-
- Python
10-
- PHP
11-
- [Markdown](#markdown)
12-
- [Scala](#scala)
7+
- Javascript, Typescript & JSX/TSX (examples: [test.js](https://github.com/graphql/graphiql/blob/main/packages/vscode-graphql-syntax/tests/__fixtures__/test.js) & [test.ts](https://github.com/graphql/graphiql/blob/main/packages/vscode-graphql-syntax/tests/__fixtures__/test.ts))
8+
- Vue (examples: [test-sfc-comp.vue](https://github.com/graphql/graphiql/blob/main/packages/vscode-graphql-syntax/tests/__fixtures__/test-sfc-comp.vue) & [test-sfc.vue](https://github.com/graphql/graphiql/blob/main/packages/vscode-graphql-syntax/tests/__fixtures__/test-sfc.vue))
9+
- Svelte (example: [test.svelte](https://github.com/graphql/graphiql/blob/main/packages/vscode-graphql-syntax/tests/__fixtures__/test.svelte))
10+
- ReasonML/ReScript (`%graphql()` ) (example: [test.re](https://github.com/graphql/graphiql/blob/main/packages/vscode-graphql-syntax/tests/__fixtures__/test.re))
11+
- Python (example: [test.py](https://github.com/graphql/graphiql/blob/main/packages/vscode-graphql-syntax/tests/__fixtures__/test.py))
12+
- PHP (example: [test.php](https://github.com/graphql/graphiql/blob/main/packages/vscode-graphql-syntax/tests/__fixtures__/test.php))
13+
- Markdown (examples: [test.md](https://github.com/graphql/graphiql/blob/main/packages/vscode-graphql-syntax/tests/__fixtures__/test.md) & [test-py.md](https://github.com/graphql/graphiql/blob/main/packages/vscode-graphql-syntax/tests/__fixtures__/test-py.md))
14+
- Scala (example: [test.scala](https://github.com/graphql/graphiql/blob/main/packages/vscode-graphql-syntax/tests/__fixtures__/test.scala))
15+
- ruby (example: [test.rb](https://github.com/graphql/graphiql/blob/main/packages/vscode-graphql-syntax/tests/__fixtures__/test.rb))
1316

1417
You'll want to install this if you do not use `graphql-config`, or want to use
1518
the highlighting with other extensions than `vscode-graphql`
1619

17-
## Embedded Language Usage
18-
19-
<span id="ts">
20-
### Javascript & Typescript
21-
22-
The following delimiters are accepted for syntax highlighting. If you are using
23-
any of these patterns and they do not work, please open an issue!
24-
25-
#### Template Literal Expressions
26-
27-
```ts
28-
const query = gql`
29-
{
30-
id
31-
}
32-
`;
33-
```
34-
35-
you can use these template tag literal expressions anywhere you like of course
36-
37-
```ts
38-
useFancyGraphQLClient(
39-
graphql`
40-
{
41-
id
42-
}
43-
`,
44-
{
45-
networkStrategy: '🚀',
46-
},
47-
);
48-
```
20+
## Contributing
4921

50-
```ts
51-
const query = gql.experimental`{ id }`;
52-
```
53-
54-
and in typescript, template tag expressions with type arguments
55-
56-
```ts
57-
const query = gql<MyType>`
58-
{
59-
id
60-
}
61-
`;
62-
```
63-
64-
#### Function Expressions
65-
66-
as well as normal function expressions with template literals
67-
68-
```ts
69-
gql('{ id }');
70-
```
71-
72-
```ts
73-
graphql(`
74-
{
75-
id
76-
}
77-
`);
78-
```
79-
80-
there is a bug with function expressions with type arguments like these that we
81-
need to fix:
82-
83-
```ts
84-
gql<MyType>('{ id }');
85-
```
86-
87-
Note, inline `""` and `''` string literals could also be delimited if needed,
88-
but we currently only delimit graphql template strings for obvious reasons
89-
90-
#### Comment-Delimited patterns
91-
92-
```ts
93-
const query = /* GraphQL */ `
94-
{
95-
id
96-
}
97-
`;
98-
```
99-
100-
```ts
101-
const query = `#graphql
102-
{ id }
103-
`;
104-
```
105-
106-
For full autocompletion, validation and other features, you can install
107-
`GraphQL.vscode-graphql`, which depends on this extension
108-
109-
<span id="markdown">
110-
111-
### Markdown
112-
113-
#### backtick code blocks
114-
115-
````markdown
116-
# Hello Jan
117-
118-
```graphql
119-
query MyQuery {}
120-
```
121-
````
122-
123-
#### embedded graphql in js & ts codeblocks
124-
125-
simple js/ts`gql` & `graphql` template tag expression support inside any
126-
backtick codeblocks.
127-
128-
````markdown
129-
# Hello Jan
130-
131-
```js
132-
const myQuery = gql`
133-
{
134-
its {
135-
query
136-
time
137-
}
138-
}
139-
`;
140-
```
141-
````
142-
143-
#### Scala
144-
145-
Using a `graphql`, `gql` or `schema` string interpolator:
22+
Feel free to open a PR to fix, enhance any language support, or even add new
23+
languages 😍
14624

147-
```scala
148-
val query = graphql"""
149-
{ id }
150-
"""
151-
val query2 = gql"""
152-
{ id }
153-
"""
154-
val query3 = schema"""
155-
{ id }
156-
"""
157-
```
25+
see:
15826

159-
Using a comment-delimited pattern:
27+
- [the grammars](https://github.com/graphql/graphiql/blob/main/packages/vscode-graphql-syntax/grammars/)
28+
- [the applicable vscode docs](https://code.visualstudio.com/api/language-extensions/syntax-highlight-guide)
16029

161-
```scala
162-
val query = """#graphql
163-
{ id }
164-
"""
165-
```
30+
### Contributor Guide: Improving a Language
16631

167-
## Other languages
168-
169-
We actually support other languages than this! just need to extend this readme
170-
even further! 🥵
32+
Whether fixing a bug or adding a new delimiter for your language, here are a few tips for you:
17133

172-
## Contributing
34+
1. TDD approach: add your bug case or new delimiter example to the relevant file in `tests/__fixtures__`
35+
1. run `yarn test -u` in the syntax extension workspace, and observe whether vscode-textmate tokenizes your example properly
36+
1. fix/update/add the relevant pattern, and repeat the above to see if the tokenization changes. you should see `meta.embedded.block.graphql`
37+
1. to test manually, run `yarn vsce:package` in the workspace and right click to install the bundled vsix extension, and open the fixture file
17338

174-
Feel free to open a PR to fix, enhance any language support, or even add new
175-
languages 😍
39+
<span id="adding-a-lang"></span>
17640

177-
see:
41+
### Contributor Guide: Adding a Language
17842

179-
- [the grammars](grammars/)
180-
- [the applicable vscode docs](https://code.visualstudio.com/api/language-extensions/syntax-highlight-guide)
43+
1. add a file to [grammars](https://github.com/graphql/graphiql/blob/main/packages/vscode-graphql-syntax/grammars/) following our other examples.
44+
1. be sure to add it to `package.json` contributions as well, in the `grammars` section. the `text.html.markdown` is for applying to markdown codeblocks
45+
1. use a scope ala `source.{lang}` from a vscode-provided syntax grammar, or a popular, official contributed grammar. To find the name of the scope for any token's highlighting, use `Developer: Inspect Editor Tokens & Scopes` from the vscode command palette.
46+
1. name it `inline.graphql.{lang}` for consistency
47+
1. add a test file `tests/__fixture__` to document example usage, and a test spec to `__tests__` to assert the snapshot, pointing to the source you created
48+
1. run `yarn test -u` in the workspace to add the snapshot
49+
1. use the snapshots to ensure your capture groups are working and serializing the graphql as expected
50+
1. in the test fixture, document all working cases and non working cases with Todo comments for common usage in your language. be sure to think of cases such as string interpolation and generics for typed languages.
51+
1. add it to the list above in the readme, with links to your test fixtures as usage documentation
52+
1. to manually test it in vscode itself, run `yarn vsce:package` in the syntax extension workspace and right click and install the bundled vsix file, then view the test fixture
18153

18254
## Usage Note
18355

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,10 @@
11
{
2-
"fileTypes": [
3-
"js",
4-
"jsx",
5-
"mjs",
6-
"cjs",
7-
"es6",
8-
"es",
9-
"esm",
10-
"ts",
11-
"tsx",
12-
"vue",
13-
"svelte",
14-
"cts",
15-
"mts"
16-
],
17-
"injectionSelector": "L:source -string -comment",
2+
"scopeName": "inline.graphql",
3+
"injectionSelector": "L:(meta.embedded.block.javascript | meta.embedded.block.typescript | source.js | source.ts | source.tsx | source.vue | source.svelte) -source.graphql -inline.graphql -string -comment",
184
"patterns": [
195
{
206
"contentName": "meta.embedded.block.graphql",
21-
"begin": "\\s*+(?:(?:(Relay)\\??\\.)(QL)|(gql|graphql|graphql\\.experimental)|(/\\* GraphQL \\*/))\\s*\\(?\\s*(`)",
7+
"begin": "\\s*+(?:(?:(Relay)\\??\\.)(QL)|(gql|graphql|graphql\\.experimental)|(/\\* GraphQL \\*/))\\s*\\(?\\s*(`|'|\")",
228
"beginCaptures": {
239
"1": {
2410
"name": "variable.other.class.js"
@@ -36,7 +22,7 @@
3622
"name": "punctuation.definition.string.template.begin.js"
3723
}
3824
},
39-
"end": "`",
25+
"end": "(`|'|\")",
4026
"endCaptures": {
4127
"0": {
4228
"name": "punctuation.definition.string.template.end.js"
@@ -46,7 +32,7 @@
4632
},
4733
{
4834
"contentName": "meta.embedded.block.graphql",
49-
"begin": "\\s*+(?:(?:(Relay)\\??\\.)(QL)|(gql|graphql|graphql\\.experimental))\\s*\\(?\\s*(?:<.*>)(`)",
35+
"begin": "\\s*+(?:(?:(Relay)\\??\\.)(QL)|(gql|graphql|graphql\\.experimental))\\s*\\(?\\s*(?:<.*>)(`|'|\")",
5036
"beginCaptures": {
5137
"1": {
5238
"name": "variable.other.class.js"
@@ -61,7 +47,7 @@
6147
"name": "punctuation.definition.string.template.begin.js"
6248
}
6349
},
64-
"end": "`",
50+
"end": "(`|'|\")",
6551
"endCaptures": {
6652
"0": {
6753
"name": "punctuation.definition.string.template.end.js"
@@ -72,7 +58,7 @@
7258
{
7359
"name": "taggedTemplates",
7460
"contentName": "meta.embedded.block.graphql",
75-
"begin": "(`|')(#graphql)",
61+
"begin": "(`|'|\")(#graphql)",
7662
"beginCaptures": {
7763
"1": {
7864
"name": "punctuation.definition.string.template.begin.js"
@@ -81,14 +67,13 @@
8167
"name": "comment.line.graphql.js"
8268
}
8369
},
84-
"end": "(`|')",
70+
"end": "(`|'|\")",
8571
"endCaptures": {
8672
"0": {
8773
"name": "punctuation.definition.string.template.end.js"
8874
}
8975
},
9076
"patterns": [{ "include": "source.graphql" }]
9177
}
92-
],
93-
"scopeName": "inline.graphql"
78+
]
9479
}

packages/vscode-graphql-syntax/grammars/graphql.markdown.codeblock.json

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,32 @@
11
{
2-
"fileTypes": [],
3-
"scopeName": "markdown.graphql.codeblock",
4-
"injectionSelector": "L:markup.fenced_code.block.markdown",
2+
"scopeName": "inline.graphql.markdown.codeblock",
3+
"injectionSelector": "L:text.html.markdown -meta.embedded.block",
54
"patterns": [
65
{
7-
"contentName": "meta.embedded.block.graphql",
8-
"begin": "(gql|graphql|GraphQL)(\\s+[^`~]*)?$",
9-
"end": "(^|\\G)(?=\\s*[`~]{3,}\\s*$)",
6+
"begin": "(^|\\G)(\\s*)(\\`{3,}|~{3,})\\s*(?i:(graphql|gql|GraphQL)(\\s+[^`~]*)?$)",
7+
"name": "markup.fenced_code.block.markdown",
8+
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
9+
"beginCaptures": {
10+
"3": {
11+
"name": "punctuation.definition.markdown"
12+
},
13+
"4": {
14+
"name": "fenced_code.block.language.markdown"
15+
},
16+
"5": {
17+
"name": "fenced_code.block.language.attributes.markdown"
18+
}
19+
},
20+
"endCaptures": {
21+
"3": {
22+
"name": "punctuation.definition.markdown"
23+
}
24+
},
1025
"patterns": [
1126
{
1227
"begin": "(^|\\G)(\\s*)(.*)",
1328
"while": "(^|\\G)(?!\\s*([`~]{3,})\\s*$)",
29+
"contentName": "meta.embedded.block.graphql",
1430
"patterns": [
1531
{
1632
"include": "source.graphql"

packages/vscode-graphql-syntax/grammars/graphql.php.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"fileTypes": ["php"],
3-
"injectionSelector": "L:source -string -comment",
2+
"scopeName": "inline.graphql.php",
3+
"injectionSelector": "L:(meta.embedded.block.php | source.php -string -comment)",
44
"patterns": [
55
{
66
"contentName": "meta.embedded.block.graphql",
@@ -126,6 +126,5 @@
126126
}
127127
]
128128
}
129-
],
130-
"scopeName": "inline.graphql.php"
129+
]
131130
}

0 commit comments

Comments
 (0)