Skip to content

Commit 0f5b678

Browse files
authored
Add language support for GYB (#1515)
1 parent a5e141a commit 0f5b678

10 files changed

+9383
-5
lines changed

.unacceptablelanguageignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@ assets/swift-docc-render
22
src/typings/node-pty.d.ts
33
src/utilities/utilities.ts
44
src/tasks/SwiftProcess.ts
5+
syntaxes/swift-gyb.tmLanguage.json
6+
test/unit-tests/syntaxes/swift.tmLanguage.json
7+
test/unit-tests/syntaxes/MagicPython.tmLanguage.json

.vscodeignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@
1414
!assets/swift-docc-render/**
1515
!assets/swift_askpass.sh
1616
!node_modules/@vscode/codicons/**
17+
!swift-gyb.language-configuration.json
18+
!syntaxes/**

package-lock.json

Lines changed: 289 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,28 @@
177177
"filenamePatterns": [
178178
"*.tutorial"
179179
]
180+
},
181+
{
182+
"id": "swift-gyb",
183+
"aliases": [
184+
"Swift GYB"
185+
],
186+
"extensions": [
187+
".swift.gyb"
188+
],
189+
"configuration": "./swift-gyb.language-configuration.json"
190+
}
191+
],
192+
"grammars": [
193+
{
194+
"language": "swift-gyb",
195+
"scopeName": "source.swift.gyb",
196+
"path": "./syntaxes/swift-gyb.tmLanguage.json",
197+
"embeddedLanguages": {
198+
"meta.embedded.block.gyb": "python",
199+
"meta.embedded.control.begin.gyb": "python",
200+
"meta.embedded.expression.gyb": "python"
201+
}
180202
}
181203
],
182204
"snippets": [
@@ -2005,7 +2027,8 @@
20052027
"pretest": "npm run compile-tests",
20062028
"soundness": "scripts/soundness.sh",
20072029
"check-package-json": "tsx ./scripts/check_package_json.ts",
2008-
"test": "vscode-test",
2030+
"test": "vscode-test && npm run grammar-test",
2031+
"grammar-test": "vscode-tmgrammar-test test/unit-tests/**/*.test.swift.gyb -g test/unit-tests/syntaxes/swift.tmLanguage.json -g test/unit-tests/syntaxes/MagicPython.tmLanguage.json",
20092032
"integration-test": "npm test -- --label integrationTests",
20102033
"unit-test": "npm test -- --label unitTests",
20112034
"coverage": "npm test -- --coverage",
@@ -2083,6 +2106,7 @@
20832106
"sinon-chai": "^3.7.0",
20842107
"source-map-support": "^0.5.21",
20852108
"strip-ansi": "^6.0.1",
2109+
"vscode-tmgrammar-test": "^0.1.3",
20862110
"svgo": "^4.0.0",
20872111
"tsconfig-paths": "^4.2.0",
20882112
"tsx": "^4.20.6",
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"brackets": [["{", "}"]],
3+
"autoClosingPairs": [
4+
["%{", "}%"],
5+
["${", "}"]
6+
],
7+
"surroundingPairs": [
8+
["%{", "}%"],
9+
["${", "}"]
10+
],
11+
"folding": {
12+
"markers": {
13+
"start": "^\\s*(?:%\\{|%[^\\{].*?:)",
14+
"end": "^\\s*(?:\\}%|%\\s*end\\b)"
15+
}
16+
}
17+
}

syntaxes/swift-gyb.tmLanguage.json

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
3+
"name": "Swift GYB",
4+
"patterns": [
5+
{ "include": "#gyb-code-block" },
6+
{ "include": "#gyb-start-control-statement" },
7+
{ "include": "#gyb-end-control-statement" },
8+
{ "include": "#gyb-expression" },
9+
{ "include": "source.swift" }
10+
],
11+
"repository": {
12+
"gyb-code-block": {
13+
"name": "meta.embedded.block.gyb",
14+
"begin": "^\\s*(%)\\{",
15+
"beginCaptures": {
16+
"1": { "name": "keyword.control.gyb" },
17+
"0": { "name": "punctuation.section.block.begin.gyb" }
18+
},
19+
"end": "\\}(%)",
20+
"endCaptures": {
21+
"1": { "name": "keyword.control.gyb" },
22+
"0": { "name": "punctuation.section.block.end.gyb" }
23+
},
24+
"patterns": [{ "include": "source.python" }]
25+
},
26+
"gyb-start-control-statement": {
27+
"name": "meta.embedded.control.begin.gyb",
28+
"begin": "^\\s*(%)(?!\\{|\\s*end\\b)",
29+
"beginCaptures": {
30+
"1": { "name": "keyword.control.flow.gyb" }
31+
},
32+
"end": ":",
33+
"endCaptures": {
34+
"0": { "name": "punctuation.separator.colon.gyb" }
35+
},
36+
"patterns": [{ "include": "source.python" }]
37+
},
38+
"gyb-end-control-statement": {
39+
"name": "meta.embedded.control.end.gyb",
40+
"match": "^\\s*%\\s*end\\b",
41+
"captures": {
42+
"0": { "name": "keyword.control.flow.gyb" }
43+
}
44+
},
45+
"gyb-expression": {
46+
"name": "meta.embedded.expression.gyb",
47+
"begin": "(\\$)\\{",
48+
"beginCaptures": {
49+
"1": { "name": "variable.other.gyb" },
50+
"0": { "name": "punctuation.section.expression.begin.gyb" }
51+
},
52+
"end": "\\}",
53+
"endCaptures": {
54+
"0": { "name": "punctuation.section.expression.end.gyb" }
55+
},
56+
"patterns": [{ "include": "source.python" }]
57+
}
58+
},
59+
"injections": {
60+
"source.swift": {
61+
"patterns": [
62+
{ "include": "#gyb-code-block" },
63+
{ "include": "#gyb-start-control-statement" },
64+
{ "include": "#gyb-end-control-statement" },
65+
{ "include": "#gyb-expression" }
66+
]
67+
},
68+
"source.python": {
69+
"patterns": [
70+
{ "include": "#gyb-code-block" },
71+
{ "include": "#gyb-start-control-statement" },
72+
{ "include": "#gyb-end-control-statement" },
73+
{ "include": "#gyb-expression" }
74+
]
75+
},
76+
"source.swift.gyb": {
77+
"patterns": [
78+
{ "include": "#gyb-code-block" },
79+
{ "include": "#gyb-start-control-statement" },
80+
{ "include": "#gyb-end-control-statement" },
81+
{ "include": "#gyb-expression" }
82+
]
83+
}
84+
},
85+
"scopeName": "source.swift.gyb",
86+
"fileTypes": ["swift.gyb"],
87+
"foldingStartMarker": "^\\s*(?:%\\{|%[^\\{].*?:)",
88+
"foldingStopMarker": "^\\s*(?:\\}%|%\\s*end\\b)"
89+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// SYNTAX TEST "source.swift.gyb" "Character struct"
2+
3+
%{
4+
// <- keyword.control.gyb
5+
// <~- punctuation.section.block.begin.gyb
6+
abilities = ['strength', 'perception', 'endurance', 'charisma', 'intelligence', 'agility', 'luck']
7+
// ^ keyword.operator.assignment.python
8+
// ^ punctuation.definition.list.begin.python
9+
// ^ punctuation.definition.string.begin.python
10+
// ^^^^^^^^ string.quoted.single.python
11+
// ^ punctuation.definition.string.end.python
12+
// ^ punctuation.separator.element.python
13+
}%
14+
// <- punctuation.section.block.end.gyb
15+
// <~- keyword.control.gyb
16+
17+
enum Hello {}
18+
19+
% for ability in abilities:
20+
// <- keyword.control.flow.gyb
21+
// <~~--- keyword.control.flow.python
22+
// ^^ keyword.control.flow.python
23+
// ^ punctuation.separator.colon.gyb
24+
print("${ability}")
25+
// <----- support.function.swift
26+
// ^ punctuation.definition.arguments.begin.swift
27+
// ^ punctuation.definition.string.begin.swift
28+
// ^ variable.other.gyb
29+
// ^ punctuation.section.expression.begin.gyb
30+
// ^ punctuation.section.expression.end.gyb
31+
// ^ punctuation.definition.string.end.swift
32+
// ^ punctuation.definition.arguments.end.swift
33+
% end
34+
// <----- meta.embedded.control.end.gyb keyword.control.flow.gyb
35+
36+
struct Character {
37+
// <------ storage.type.struct.swift
38+
// ^^^^^^^^^ entity.name.type.struct.swift
39+
// ^ punctuation.definition.type.begin.swift
40+
let name: String
41+
// ^^^ keyword.other.declaration-specifier.swift
42+
// ^^^^ meta.definition.type.body.swift
43+
// ^^^^^^ support.type.swift
44+
45+
% for ability in abilities:
46+
// ^ keyword.control.flow.gyb
47+
// ^^^ keyword.control.flow.python
48+
// ^^ keyword.control.flow.python
49+
// ^ punctuation.separator.colon.gyb
50+
let ${ability}: Int
51+
// ^^^ keyword.other.declaration-specifier.swift
52+
// ^ variable.other.gyb
53+
// ^^ punctuation.section.expression.begin.gyb
54+
// ^ punctuation.section.expression.end.gyb
55+
% end
56+
// ^^^^^ meta.embedded.control.end.gyb keyword.control.flow.gyb
57+
58+
%{
59+
// ^ keyword.control.gyb
60+
// ^ punctuation.section.block.begin.gyb
61+
for i in range(10):
62+
// ^^^^^ support.function.builtin.python
63+
print(i)
64+
}%
65+
// ^ punctuation.section.block.end.gyb
66+
// ^ keyword.control.gyb
67+
68+
enum Error {
69+
case notFound
70+
71+
% for ability in abilities:
72+
case ${ability}
73+
% end
74+
}
75+
}
76+
// <- punctuation.definition.type.end.swift
77+
78+
enum World {}
79+
80+
% for ability in abilities:
81+
// <- keyword.control.flow.gyb
82+
// <~~--- keyword.control.flow.python
83+
// ^^ keyword.control.flow.python
84+
// ^ punctuation.separator.colon.gyb
85+
print("${ability}")
86+
// <----- support.function.swift
87+
// ^ punctuation.definition.arguments.begin.swift
88+
// ^ punctuation.definition.string.begin.swift
89+
// ^ variable.other.gyb
90+
// ^ punctuation.section.expression.begin.gyb
91+
// ^ punctuation.section.expression.end.gyb
92+
// ^ punctuation.definition.string.end.swift
93+
// ^ punctuation.definition.arguments.end.swift
94+
% end
95+
// <----- meta.embedded.control.end.gyb keyword.control.flow.gyb
96+
97+
struct SimpleCharacter {
98+
// <------ storage.type.struct.swift
99+
// ^^^^^^^^^^^^^^^ entity.name.type.struct.swift
100+
// ^ punctuation.definition.type.begin.swift
101+
let name: String
102+
// ^^^ keyword.other.declaration-specifier.swift
103+
// ^^^^ meta.definition.type.body.swift
104+
// ^^^^^^ support.type.swift
105+
106+
% for ability in abilities:
107+
let ${ability}: Int
108+
% end
109+
}
110+
// <- punctuation.definition.type.end.swift
111+

0 commit comments

Comments
 (0)