Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 9caa247

Browse files
authoredAug 6, 2024··
Recognize GraphQL strings passed to JavaScript functions (#109)
Some JavaScript GraphQL frameworks use well-known functions rather than tagged template literals. This change introduces basic support for these cases via a new `g:graphql_javascript_functions` variable (["graphql"]). This is implemented as a bit of a hack on top of the existing tagged template support to avoid introducing new syntax regions: Tagged template: graphql` Function call: graphql(` Syntax pattern: (graphql|graphql\()` This is a good-enough place to start, and the overall approach gives us room to iterate later if we want to revisit the implementation.
1 parent 73fbf5f commit 9caa247

File tree

7 files changed

+83
-6
lines changed

7 files changed

+83
-6
lines changed
 

‎README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,22 @@ The list of recognized tag names is defined by the `g:graphql_javascript_tags`
6868
variable, which defaults to `["gql", "graphql", "Relay.QL"]`. This can also
6969
be set on a per-buffer basis using the `b:graphql_javascript_tags` variable.
7070

71+
Untagged template literals passed as the first argument to specific functions
72+
can also be recognized. `g:graphql_javascript_functions` defines this list of
73+
functions, which defaults to `["graphql"]`. This list can also be set on a
74+
per-buffer basis using the `b:graphql_javascript_functions` variable.
75+
76+
```javascript
77+
const query = graphql(`
78+
{
79+
user(id: ${uid}) {
80+
firstName
81+
lastName
82+
}
83+
}
84+
`;
85+
```
86+
7187
You can also add a `# gql` or `# graphql` comment at the start of a template
7288
string to indicate that its contents should be considered GraphQL syntax.
7389

‎after/syntax/javascript/graphql.vim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323

2424
call graphql#embed_syntax('GraphQLSyntax')
2525

26-
let s:tags = '\%(' . join(graphql#javascript_tags(), '\|') . '\)'
26+
let s:functions = map(copy(graphql#javascript_functions()), 'v:val .. "("')
27+
let s:tags = '\%(' . join(graphql#javascript_tags() + s:functions, '\|') . '\)'
2728

2829
if graphql#has_syntax_group('jsTemplateExpression')
2930
" pangloss/vim-javascript

‎after/syntax/typescript/graphql.vim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323

2424
call graphql#embed_syntax('GraphQLSyntax')
2525

26-
let s:tags = '\%(' . join(graphql#javascript_tags(), '\|') . '\)'
26+
let s:functions = map(copy(graphql#javascript_functions()), 'v:val .. "("')
27+
let s:tags = '\%(' . join(graphql#javascript_tags() + s:functions, '\|') . '\)'
2728

2829
exec 'syntax region graphqlTemplateString matchgroup=typescriptTemplate start=+' . s:tags . '\@20<=`+ skip=+\\`+ end=+`+ contains=@GraphQLSyntax,typescriptTemplateSubstitution extend'
2930
exec 'syntax match graphqlTaggedTemplate +' . s:tags . '\ze`+ nextgroup=graphqlTemplateString'

‎autoload/graphql.vim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ function! graphql#has_syntax_group(group) abort
6060
return v:true
6161
endfunction
6262

63+
function! graphql#javascript_functions() abort
64+
return graphql#var('graphql_javascript_functions', ['graphql'])
65+
endfunction
66+
6367
function! graphql#javascript_tags() abort
6468
return graphql#var('graphql_javascript_tags', ['gql', 'graphql', 'Relay.QL'])
6569
endfunction

‎doc/graphql.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ supported.
2525

2626
*graphql-javascript-options*
2727

28+
*g:graphql_javascript_functions*
29+
*b:graphql_javascript_functions*
30+
|g:graphql_javascript_functions| list of strings
31+
32+
Default: `["graphql"]`
33+
34+
This variable lists the JavaScript function names that will be recognized as
35+
receiving GraphQL template literal strings as their first argument.
36+
2837
*g:graphql_javascript_tags*
2938
*b:graphql_javascript_tags*
3039
|g:graphql_javascript_tags| list of strings

‎test/javascript/default.vader

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
Before:
2-
Save g:graphql_javascript_tags
2+
Save b:graphql_javascript_functions
3+
Save b:graphql_javascript_tags
34

45
setlocal shiftwidth=2
56
source ../after/indent/javascript.vim
@@ -69,16 +70,46 @@ Execute (Syntax assertions):
6970
AssertEqual 'javascript', b:current_syntax
7071
AssertEqual 'graphqlName', SyntaxOf('user')
7172

73+
Given javascript (Template literal with a graphql() function):
74+
const query = graphql(`
75+
{
76+
user(id: ${uid}) {
77+
firstName
78+
lastName
79+
}
80+
}
81+
`;
82+
83+
Execute (Syntax assertions):
84+
AssertEqual 'javascript', b:current_syntax
85+
AssertEqual 'graphqlName', SyntaxOf('user')
86+
7287
Given javascript (Template literal):
7388
const s = `text`;
7489

7590
Execute (Untagged template literals aren't matched ):
7691
AssertNotEqual 'graphqlTemplateString', SyntaxOf('`')
7792

93+
Given javascript (Custom function):
94+
const query = gql(`
95+
{
96+
user(id: ${uid}) {
97+
firstName
98+
lastName
99+
}
100+
}
101+
`;
102+
103+
Execute (Function names can be customized):
104+
let b:graphql_javascript_functions = ['gql']
105+
source ../after/syntax/javascript/graphql.vim
106+
AssertEqual 'javascript', b:current_syntax
107+
AssertEqual 'graphqlName', SyntaxOf('user')
108+
78109
Given javascript (Custom tag):
79110
const query = GraphQL.Tag`{}`;
80111

81112
Execute (Tag names can be customized):
82-
let g:graphql_javascript_tags = ['GraphQL.Tag']
113+
let b:graphql_javascript_tags = ['GraphQL.Tag']
83114
source ../after/syntax/javascript/graphql.vim
84115
AssertEqual 'graphqlTaggedTemplate', SyntaxOf('GraphQL.Tag')

‎test/typescript/default.vader

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
Before:
2-
Save g:graphql_javascript_tags
2+
Save b:graphql_javascript_functions
3+
Save b:graphql_javascript_tags
34

45
setlocal shiftwidth=2
56
source ../after/indent/typescript.vim
@@ -48,7 +49,7 @@ Given typescript (Custom tag):
4849
const query = GraphQL.Tag`{}`;
4950

5051
Execute (Tag names can be customized):
51-
let g:graphql_javascript_tags = ['GraphQL.Tag']
52+
let b:graphql_javascript_tags = ['GraphQL.Tag']
5253
source ../after/syntax/typescript/graphql.vim
5354
AssertEqual 'graphqlTaggedTemplate', SyntaxOf('GraphQL.Tag')
5455

@@ -85,3 +86,17 @@ Given typescript (Template literal with `# graphql` comment):
8586
Execute (Syntax assertions):
8687
AssertEqual 'typescript', b:current_syntax
8788
AssertEqual 'graphqlName', SyntaxOf('user')
89+
90+
Given typescript (Template literal with a graphql() function):
91+
const query = graphql(`
92+
{
93+
user(id: ${uid}) {
94+
firstName
95+
lastName
96+
}
97+
}
98+
`;
99+
100+
Execute (Syntax assertions):
101+
AssertEqual 'typescript', b:current_syntax
102+
AssertEqual 'graphqlName', SyntaxOf('user')

0 commit comments

Comments
 (0)
Please sign in to comment.