Skip to content

Injections not applied in grammar that was itself injected #152

Closed
@wlach

Description

@wlach

(Redirecting from sveltejs/language-tools#1094)

The svelte vscode plugin uses injections to create a set of matching rules to syntax highlight embedded javascript blocks, like the following:

This is a markdown document.

```svelte
<script>
  var x = 1;
</script>
Foo
```

https://github.com/sveltejs/language-tools/blob/89d6c87f410f4465a1ef7c88f28fa0e8c6603bb9/packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml#L18

However, in the case of a svelte component embedded in a markdown file, these injection rules do not seem to be applied (only the rules defined later in the textmate definition) and thus syntax highlighting is not applied correctly. A small patch to the script matching logic to manually add the rule that we were relying on confirms this (by fixing the problem for bare script tags like the one cited above):

diff --git a/packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml b/packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml
index 5a7ebc4..197b69d 100644
--- a/packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml
+++ b/packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml
@@ -502,6 +502,7 @@ repository:
       patterns: [ include: '#tags-lang-start-attributes' ]
     # Fallback to default language.
     - include: '#tags-lang-start-attributes'
+    - patterns: [{begin: '(?<=>)(?!</)', end: '(?=</)', name: meta.embedded.block.svelte, patterns: [{ include: source.js }]}]
 
   # Void element tags. They must be treated separately due to their lack of end nodes.
   # A void element cannot be differentiated from other tags, unless you look at their name.

Is it expected that injections will not be applied inside embedded contexts like these? This seems vaguely similar to #122 which was marked as fixed, though it seems like it might be slightly different. It's also not clear to me if this is an issue with vscode-textmate or vscode's use of it, so feel free to redirect as needed.

It's probably possible to workaround this (to some degree) in the svelte plugin using the pattern above, though I think the code would be longer and less elegant than the injection-based approach (there's also one language extension injection that I'm not sure how to reimplement offhand: https://github.com/sveltejs/language-tools/blob/89d6c87f410f4465a1ef7c88f28fa0e8c6603bb9/packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml#L91).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions