Skip to content

Commit 3eb4798

Browse files
committed
Merge branch 'master' into pr/javascript/fix-indentation
2 parents d60cbc0 + 65a7571 commit 3eb4798

10 files changed

+588
-21
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ jobs:
6060

6161
# https://github.com/actions/checkout
6262
- name: Checkout Packages
63-
uses: actions/checkout@v3
63+
uses: actions/checkout@v4
6464
with:
6565
path: st_syntax_tests/Data/Packages
6666

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
%YAML 1.2
2+
---
3+
# http://www.sublimetext.com/docs/syntax.html
4+
# highlight tagged template strings
5+
scope: source.css.js-template
6+
version: 2
7+
hidden: true
8+
9+
extends: Packages/CSS/CSS.sublime-syntax
10+
11+
variables:
12+
13+
ident_start: (?:{{nmstart}}|\${)
14+
15+
contexts:
16+
17+
prototype:
18+
- meta_prepend: true
19+
- include: scope:source.js#text-interpolations
20+
21+
strings-content:
22+
- meta_prepend: true
23+
- include: scope:source.js#string-interpolations
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
%YAML 1.2
2+
---
3+
# http://www.sublimetext.com/docs/syntax.html
4+
# highlight tagged template strings
5+
scope: text.html.js-template
6+
version: 2
7+
hidden: true
8+
9+
extends: Packages/HTML/HTML.sublime-syntax
10+
11+
variables:
12+
13+
tag_name_start: (?:[A-Za-z]|\${)
14+
15+
contexts:
16+
17+
prototype:
18+
- meta_prepend: true
19+
- include: scope:source.js#text-interpolations
20+
21+
cdata-content:
22+
- meta_prepend: true
23+
- include: scope:source.js#string-interpolations
24+
25+
script-javascript-content:
26+
- meta_include_prototype: false
27+
- match: '{{script_content_begin}}'
28+
captures:
29+
1: comment.block.html punctuation.definition.comment.begin.html
30+
pop: 1 # make sure to match only once
31+
embed: scope:source.js.js-template
32+
embed_scope: source.js.embedded.html
33+
escape: '{{script_content_end}}'
34+
escape_captures:
35+
1: source.js.embedded.html
36+
2: comment.block.html punctuation.definition.comment.end.html
37+
3: source.js.embedded.html
38+
4: comment.block.html punctuation.definition.comment.end.html
39+
40+
script-json-content:
41+
- meta_include_prototype: false
42+
- match: '{{script_content_begin}}'
43+
captures:
44+
1: comment.block.html punctuation.definition.comment.begin.html
45+
pop: 1 # make sure to match only once
46+
embed: scope:source.json.js-template
47+
embed_scope: source.json.embedded.html
48+
escape: '{{script_content_end}}'
49+
escape_captures:
50+
1: source.json.embedded.html
51+
2: comment.block.html punctuation.definition.comment.end.html
52+
3: source.json.embedded.html
53+
4: comment.block.html punctuation.definition.comment.end.html
54+
55+
style-css-content:
56+
- meta_include_prototype: false
57+
- match: '{{style_content_begin}}'
58+
captures:
59+
1: comment.block.html punctuation.definition.comment.begin.html
60+
pop: 1 # make sure to match only once
61+
embed: scope:source.css.js-template
62+
embed_scope: source.css.embedded.html
63+
escape: '{{style_content_end}}'
64+
escape_captures:
65+
1: source.css.embedded.html
66+
2: comment.block.html punctuation.definition.comment.end.html
67+
3: source.css.embedded.html
68+
4: comment.block.html punctuation.definition.comment.end.html
69+
70+
tag-event-attribute-value:
71+
- match: \"
72+
scope:
73+
meta.string.html string.quoted.double.html
74+
punctuation.definition.string.begin.html
75+
embed: scope:source.js.js-template
76+
embed_scope: meta.string.html meta.embedded.html source.js.embedded.html
77+
escape: \"
78+
escape_captures:
79+
0: meta.string.html string.quoted.double.html
80+
punctuation.definition.string.end.html
81+
- match: \'
82+
scope:
83+
meta.string.html string.quoted.single.html
84+
punctuation.definition.string.begin.html
85+
embed: scope:source.js.js-template
86+
embed_scope: meta.string.html meta.embedded.html source.js.embedded.html
87+
escape: \'
88+
escape_captures:
89+
0: meta.string.html string.quoted.single.html
90+
punctuation.definition.string.end.html
91+
- include: else-pop
92+
93+
tag-style-attribute-value:
94+
- match: \"
95+
scope:
96+
meta.string.html string.quoted.double.html
97+
punctuation.definition.string.begin.html
98+
embed: scope:source.css.js-template#rule-list-body
99+
embed_scope: meta.string.html meta.embedded.html source.css.embedded.html
100+
escape: \"
101+
escape_captures:
102+
0: meta.string.html string.quoted.double.html
103+
punctuation.definition.string.end.html
104+
- match: \'
105+
scope:
106+
meta.string.html string.quoted.single.html
107+
punctuation.definition.string.begin.html
108+
embed: scope:source.css.js-template#rule-list-body
109+
embed_scope: meta.string.html meta.embedded.html source.css.embedded.html
110+
escape: \'
111+
escape_captures:
112+
0: meta.string.html string.quoted.single.html
113+
punctuation.definition.string.end.html
114+
- include: else-pop
115+
116+
tag-attribute-value-content:
117+
- meta_prepend: true
118+
- include: scope:source.js#string-interpolations
119+
120+
strings-common-content:
121+
- meta_prepend: true
122+
- include: scope:source.js#string-interpolations
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
%YAML 1.2
2+
---
3+
# http://www.sublimetext.com/docs/syntax.html
4+
# highlight tagged template strings
5+
scope: source.json.js-template
6+
version: 2
7+
hidden: true
8+
9+
extends: Packages/JSON/JSON.sublime-syntax
10+
11+
contexts:
12+
prototype:
13+
- meta_prepend: true
14+
- include: scope:source.js#text-interpolations
15+
16+
string-prototype:
17+
- meta_prepend: true
18+
- include: scope:source.js#string-interpolations
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
%YAML 1.2
2+
---
3+
# http://www.sublimetext.com/docs/syntax.html
4+
# highlight tagged template strings
5+
scope: source.js.js-template
6+
version: 2
7+
hidden: true
8+
9+
extends: Packages/JavaScript/JavaScript.sublime-syntax
10+
11+
contexts:
12+
13+
prototype:
14+
- meta_prepend: true
15+
- include: scope:source.js#text-interpolations
16+
17+
string-content:
18+
- meta_prepend: true
19+
- include: scope:source.js#string-interpolations

JavaScript/Indentation Rules.tmPreferences

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
\}
2424
# dedent closing brackets
2525
| \]
26+
# dedent closing tagged templates
27+
| `
2628
# detent `case ... :`
2729
| case\b.*:
2830
# detent `default:`
@@ -38,6 +40,8 @@
3840
# indent after opening braces (may be followed by whitespace or comments)
3941
# but exclude lines such as `extern "C" {`
4042
.* \{ (?: \s* /\*.*\*/ )* \s* (?: //.* )? $
43+
# indent after opening tagged template: e.g.: "css`"
44+
| .* \w+ \s* `
4145
# indent after `case ... :`
4246
| case\b.*:
4347
# indent after `default:`

JavaScript/JavaScript.sublime-syntax

Lines changed: 82 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ variables:
107107
# '@' followed by a pattern like \S but excluding literal '*' and '@'.
108108
jsdoc_block_tag: \@[^\n\t\f\v *@]+
109109

110+
leading_wspace: (?:^\s*)
111+
trailing_wspace: (?:\s*$\n?)
112+
110113
contexts:
111114
main:
112115
- meta_include_prototype: false # don't match comments before shebang
@@ -1011,8 +1014,7 @@ contexts:
10111014
- include: decorator-name
10121015
- include: object-property
10131016

1014-
- match: (?=`)
1015-
push: literal-string-template
1017+
- include: literal-string-templates
10161018

10171019
- match: (?={{function_call_after_lookahead}})
10181020
push: function-call-arguments
@@ -1078,8 +1080,7 @@ contexts:
10781080
left-expression-end:
10791081
- include: expression-break
10801082

1081-
- match: (?=`)
1082-
push: literal-string-template
1083+
- include: literal-string-templates
10831084

10841085
- match: '{{function_call_after_lookahead}}'
10851086
push: function-call-arguments
@@ -1223,16 +1224,76 @@ contexts:
12231224
pop: 1
12241225
- include: string-content
12251226

1227+
literal-string-templates:
1228+
- match: (?=(?:{{identifier_name}}\s*)?`)
1229+
push: literal-string-template
1230+
12261231
literal-string-template:
1227-
- match: \`
1228-
scope: punctuation.definition.string.begin.js
1232+
# Notes:
1233+
# Consume trailing whitespace after opening punctuation
1234+
# and leading whitespace in front of closing punctuation
1235+
# to maintain JavaScript indentation rules until embedded
1236+
# code really begins/ends. It's required for embedded code
1237+
# to be indented using global JavaScript indentation rules.
1238+
- match: (css)\s*((\`){{trailing_wspace}}?)
1239+
captures:
1240+
1: variable.function.tagged-template.js
1241+
2: meta.string.js string.quoted.other.js
1242+
3: punctuation.definition.string.begin.js
1243+
embed: scope:source.css.js-template
1244+
embed_scope: meta.string.js source.css.embedded.js
1245+
escape: '{{leading_wspace}}?(\`)'
1246+
escape_captures:
1247+
0: meta.string.js string.quoted.other.js
1248+
1: punctuation.definition.string.end.js
1249+
pop: 1
1250+
- match: (html)\s*((\`){{trailing_wspace}}?)
1251+
captures:
1252+
1: variable.function.tagged-template.js
1253+
2: meta.string.js string.quoted.other.js
1254+
3: punctuation.definition.string.begin.js
1255+
embed: scope:text.html.js-template
1256+
embed_scope: meta.string.js text.html.embedded.js
1257+
escape: '{{leading_wspace}}?(\`)'
1258+
escape_captures:
1259+
0: meta.string.js string.quoted.other.js
1260+
1: punctuation.definition.string.end.js
1261+
pop: 1
1262+
- match: (js)\s*((\`){{trailing_wspace}}?)
1263+
captures:
1264+
1: variable.function.tagged-template.js
1265+
2: meta.string.js string.quoted.other.js
1266+
3: punctuation.definition.string.begin.js
1267+
embed: scope:source.js.js-template
1268+
embed_scope: meta.string.js source.js.embedded.js
1269+
escape: '{{leading_wspace}}?(\`)'
1270+
escape_captures:
1271+
0: meta.string.js string.quoted.other.js
1272+
1: punctuation.definition.string.end.js
1273+
pop: 1
1274+
- match: (json)\s*((\`){{trailing_wspace}}?)
1275+
captures:
1276+
1: variable.function.tagged-template.js
1277+
2: meta.string.js string.quoted.other.js
1278+
3: punctuation.definition.string.begin.js
1279+
embed: scope:source.json.js-template
1280+
embed_scope: meta.string.js source.json.embedded.js
1281+
escape: '{{leading_wspace}}?(\`)'
1282+
escape_captures:
1283+
0: meta.string.js string.quoted.other.js
1284+
1: punctuation.definition.string.end.js
1285+
pop: 1
1286+
- match: (?:({{identifier_name}})\s*)?(\`)
1287+
captures:
1288+
1: variable.function.tagged-template.js
1289+
2: meta.string.js string.quoted.other.js punctuation.definition.string.begin.js
12291290
set: literal-string-template-content
12301291

12311292
literal-string-template-content:
12321293
- meta_include_prototype: false
1233-
- meta_scope: meta.string.js string.quoted.other.js
1294+
- meta_content_scope: meta.string.js string.quoted.other.js
12341295
- match: \`
1235-
scope: punctuation.definition.string.end.js
1296+
scope: meta.string.js string.quoted.other.js punctuation.definition.string.end.js
12361297
pop: 1
12371298
- include: string-interpolations
12381299
- include: string-content
@@ -1250,13 +1311,22 @@ contexts:
12501311

12511312
string-interpolation-content:
12521313
- clear_scopes: 1
1314+
- meta_scope: meta.interpolation.js
1315+
- meta_content_scope: source.js.embedded
1316+
- include: text-interpolation-content
1317+
1318+
text-interpolations:
1319+
- match: \$\{
1320+
scope: punctuation.section.interpolation.begin.js
1321+
push: text-interpolation-content
1322+
1323+
text-interpolation-content:
12531324
- meta_scope: meta.interpolation.js
12541325
- meta_content_scope: source.js.embedded
12551326
- match: \}
12561327
scope: punctuation.section.interpolation.end.js
12571328
pop: 1
1258-
- match: (?=\S)
1259-
push: expression
1329+
- include: expressions
12601330

12611331
regexp-complete:
12621332
- match: '/'
@@ -2088,9 +2158,7 @@ contexts:
20882158
- function-name-meta
20892159
- literal-variable-base
20902160

2091-
- match: '{{identifier_name}}(?={{nothing}}`)'
2092-
scope: variable.function.tagged-template.js
2093-
pop: 1
2161+
- include: literal-string-template
20942162

20952163
- match: '{{constant_identifier}}(?=\s*(?:{{dot_accessor}}|\[))'
20962164
scope: support.class.js
@@ -2523,9 +2591,7 @@ contexts:
25232591
- match: '(?=#?{{identifier_name}}{{function_call_after_lookahead}})'
25242592
set: call-method-name
25252593

2526-
- match: '{{identifier_name}}(?={{nothing}}`)'
2527-
scope: variable.function.tagged-template.js
2528-
pop: 1
2594+
- include: literal-string-template
25292595

25302596
- include: object-property-base
25312597
- include: else-pop

JavaScript/tests/syntax_test_js.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,6 @@ tag `template`;
273273
// <- variable.function.tagged-template
274274
// ^^^^^^^^^^ meta.string string.quoted.other
275275

276-
tag/**/`template`;
277-
// <- variable.function.tagged-template
278-
279276
x ? y // y is a template tag!
280277
`template` : z;
281278
// ^ keyword.operator.ternary
@@ -1051,7 +1048,7 @@ foo
10511048
// ^^^ variable.function.tagged-template
10521049
// ^^ meta.string string.quoted.other punctuation.definition.string
10531050
1054-
foo.tag/**/``;
1051+
foo.tag ``;
10551052
// ^^^ variable.function.tagged-template
10561053
10571054
return new Promise(resolve => preferenceObject.set({value}, resolve));

0 commit comments

Comments
 (0)