Skip to content

Commit 121f4bd

Browse files
authored
(fix) more robust syntax highlighting (#743)
Split up special tags and html tags matching logic into start and end to deal with whitespace inside the tags. This is needed due to the new way prettier-plugin-svelte 2.0 formats inline elements.
1 parent c3de841 commit 121f4bd

File tree

1 file changed

+54
-44
lines changed

1 file changed

+54
-44
lines changed

packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml

Lines changed: 54 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,8 @@ repository:
187187
special-tags:
188188
patterns:
189189
- include: '#special-tags-void'
190-
- include: '#special-tags-block'
190+
- include: '#special-tags-block-begin'
191+
- include: '#special-tags-block-end'
191192

192193
# Special tag keywords, like `#if` and `/await`.
193194
special-tags-keywords:
@@ -277,39 +278,33 @@ repository:
277278
patterns: [ include: '#special-tags-modes' ]
278279

279280
# Special tag blocks like `{#if}...{/if}`.
280-
# Notice that we're matching _around_ these blocks.
281-
special-tags-block:
282-
begin: (?={\s*#([a-z]*))
283-
end: (?<={\s*/\1\s*})
284-
name: meta.scope.special.$1.svelte
285-
patterns:
286-
# Start node.
281+
# Split up into start and end because we don't need to preserve the name
282+
# inside and because it makes whitespace matching logic more robust
283+
special-tags-block-begin:
287284
# This pattern is technically not correct,
288285
# as the (#|:|/)[logic] keywords do not care about whitespace between it and the { bracket.
289286
# This means newlines are actually valid!
290287
# However, deciphering what is logic and what is interpolation would be stupidly tedious. So we don't.
291-
- begin: \G({)\s*(#([a-z]*))
292-
beginCaptures:
293-
1: { name: punctuation.definition.block.begin.svelte }
294-
2: { patterns: [ include: '#special-tags-keywords' ] }
295-
end: \}
296-
endCaptures: { 0: { name: punctuation.definition.block.end.svelte } }
297-
name: meta.special.$3.start.svelte
298-
patterns: [ include: '#special-tags-modes' ]
299-
# End node.
288+
begin: ({)\s*(#([a-z]*))
289+
end: (})
290+
name: meta.special.$3.svelte meta.special.start.svelte
291+
beginCaptures:
292+
1: { name: punctuation.definition.block.begin.svelte }
293+
2: { patterns: [ include: '#special-tags-keywords' ] }
294+
endCaptures: { 0: { name: punctuation.definition.block.end.svelte } }
295+
patterns: [ include: '#special-tags-modes' ]
296+
297+
special-tags-block-end:
300298
# This is again technically not correct, and due to the same whitespacing reasons.
301299
# However... just don't introduce newlines in `{/if}` blocks. 'cuz that's weird.
302-
- match: ({)\s*(/([a-z]*))\s*(})
303-
captures:
304-
1: { name: punctuation.definition.block.begin.svelte }
305-
2: { patterns: [ include: '#special-tags-keywords' ] }
306-
4: { name: punctuation.definition.block.end.svelte }
307-
name: meta.special.$3.end.svelte
308-
# Block content. (inbetween start and end nodes)
309-
- begin: (?<=})
310-
end: (?={\s*/)
311-
# Introduce our new scope.
312-
patterns: [ include: '#scope' ]
300+
begin: ({)\s*(/([a-z]*))
301+
end: (})
302+
name: meta.special.$3.svelte meta.special.end.svelte
303+
beginCaptures:
304+
1: { name: punctuation.definition.block.begin.svelte }
305+
2: { patterns: [ include: '#special-tags-keywords' ] }
306+
endCaptures:
307+
1: { name: punctuation.definition.block.end.svelte }
313308

314309
# ------------
315310
# ATTRIBUTES
@@ -406,10 +401,11 @@ repository:
406401
# All tags together. Used whenever a new nested scope is introduced (and the root scope, of course).
407402
tags:
408403
patterns:
409-
# The order is important here - void tags need to matched before block tags.
404+
# The order is important here - void tags need to matched before block tags and end before start.
410405
- include: '#tags-lang'
411406
- include: '#tags-void'
412-
- include: '#tags-general'
407+
- include: '#tags-general-end'
408+
- include: '#tags-general-start'
413409

414410
# -- TAG COMPONENTS
415411

@@ -433,6 +429,14 @@ repository:
433429

434430
# Attributes for tag start nodes. Meant to start immediately after the `<name` section.
435431
tags-start-attributes:
432+
begin: \G
433+
end: (?=/?>)
434+
endCaptures: { 0: { name: punctuation.definition.tag.end.svelte } }
435+
name: meta.tag.start.svelte
436+
patterns: [ include: '#attributes' ]
437+
438+
# Same as tags-start-attributes but slightly adjusted for special script/style/template tags.
439+
tags-lang-start-attributes:
436440
begin: \G
437441
end: (?=/>)|>
438442
endCaptures: { 0: { name: punctuation.definition.tag.end.svelte } }
@@ -456,12 +460,6 @@ repository:
456460
3: { name: meta.tag.end.svelte punctuation.definition.tag.end.svelte }
457461
4: { name: meta.tag.start.svelte punctuation.definition.tag.end.svelte }
458462

459-
# Content of an element - inbetween the start and end nodes.
460-
tags-block-content:
461-
begin: (?<!/>)(?<=>)
462-
end: (?=</)
463-
patterns: [ include: '#scope' ]
464-
465463
# -- TAG TYPES
466464

467465
# Language tags - they are handled differently for the purposes of language injection.
@@ -476,9 +474,9 @@ repository:
476474
- begin: \G(?=\s*(type|lang)\s*=\s*(['"]|)(?:text/)?(\w+)\2)
477475
end: (?=</|/>)
478476
name: meta.lang.$3.svelte
479-
patterns: [ include: '#tags-start-attributes' ]
477+
patterns: [ include: '#tags-lang-start-attributes' ]
480478
# Fallback to default language.
481-
- include: '#tags-start-attributes'
479+
- include: '#tags-lang-start-attributes'
482480

483481
# Void element tags. They must be treated separately due to their lack of end nodes.
484482
# A void element cannot be differentiated from other tags, unless you look at their name.
@@ -495,14 +493,26 @@ repository:
495493
patterns: [ include: '#attributes' ]
496494

497495
# All other tags, including custom/special Svelte tags.
498-
tags-general:
499-
begin: <([^/\s>]*)
500-
end: </\1\s*>|/>
496+
# Split up into start and end because we don't need to preserve the name
497+
# inside and because it makes whitespace matching logic more robust
498+
tags-general-start:
499+
begin: (<)([^/\s>]*)
500+
end: (>)
501501
beginCaptures: { 0: { patterns: [ include: '#tags-start-node' ] } }
502-
endCaptures: { 0: { patterns: [ include: '#tags-end-node' ] } }
503-
name: meta.scope.tag.$1.svelte
502+
endCaptures:
503+
1: { name: meta.tag.start.svelte punctuation.definition.tag.end.svelte }
504+
name: meta.scope.tag.$2.svelte
504505
patterns:
505506
- include: '#tags-start-attributes'
506-
- include: '#tags-block-content'
507+
508+
tags-general-end:
509+
begin: (</)([^/\s>]*)
510+
end: (>)
511+
beginCaptures:
512+
1: { name: meta.tag.end.svelte punctuation.definition.tag.begin.svelte }
513+
2: { name: meta.tag.end.svelte, patterns: [ include: '#tags-name' ] }
514+
endCaptures:
515+
1: { name: meta.tag.end.svelte punctuation.definition.tag.end.svelte }
516+
name: meta.scope.tag.$2.svelte
507517

508518
...

0 commit comments

Comments
 (0)