diff --git a/packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml b/packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml
index e2c689077..e925ff2f2 100644
--- a/packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml
+++ b/packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml
@@ -234,11 +234,38 @@ repository:
special-tags-modes:
patterns:
# Expressions or simple values.
- - begin: (?<=(if|key|then|catch|snippet|html|render).*?)\G
+ - begin: (?<=(if|key|then|catch|html|render).*?)\G
end: (?=})
name: meta.embedded.expression.svelte source.ts
patterns: [ include: source.ts ]
+ # Snippet blocks - special because of how source.ts will parse generics: If it realizes "oh this is a function definition" it will
+ # go into arrow function parsing mode and not stop until it finds a `=>`, which means it will go past the `}` snippet open boundary
+ # and fuck up the rest of the file syntax highlighting
+ - begin: (?<=snippet.*?)\G
+ end: (?=})
+ name: meta.embedded.expression.svelte source.ts
+ patterns:
+ # Match an identifier, but only if it is before a generic
+ - match: \G\s*([_$[:alpha:]][_$[:alnum:]]*)\s*(?=<)
+ captures:
+ 1: { name: entity.name.function.ts }
+ # Match optional `<` ... `>` with inner as source.ts
+ - begin: (?<=<)
+ end: (?=>)
+ contentName: meta.type.parameters.ts
+ patterns: [ include: source.ts ]
+ # Match the `(...)` but not starting at `(` because then TS would see it as an arrow function and parse past our snippet open boundary
+ - begin: (?<=>\s*\()
+ end: (?=})
+ name: meta.embedded.expression.svelte source.ts
+ patterns: [ include: source.ts ]
+ # If the above three don't match (because there's no generic) then this one kicks in
+ - begin: \G
+ end: (?=})
+ name: meta.embedded.expression.svelte source.ts
+ patterns: [ include: source.ts ]
+
# Const.
- begin: (?<=const.*?)\G
end: (?=})
diff --git a/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/SnippetBlock.ts b/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/SnippetBlock.ts
index 7dd6633a8..f08e8c960 100644
--- a/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/SnippetBlock.ts
+++ b/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/SnippetBlock.ts
@@ -116,7 +116,7 @@ export function handleSnippet(
'const ',
[snippetBlock.expression.start, snippetBlock.expression.end],
IGNORE_POSITION_COMMENT,
- ' = ('
+ ` = ${snippetBlock.typeParams ? `<${snippetBlock.typeParams}>` : ''}(`
];
if (parameters) {
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/snippet-generics.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/snippet-generics.v5/expectedv2.ts
new file mode 100644
index 000000000..460b114ba
--- /dev/null
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/snippet-generics.v5/expectedv2.ts
@@ -0,0 +1,17 @@
+///
+;function $$render() {
+ const generic/*Ωignore_positionΩ*/ = (val: T)/*Ωignore_startΩ*/: ReturnType/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {
+ val;
+};return __sveltets_2_any(0)}; const complex_generic/*Ωignore_positionΩ*/ = ">>(val: T)/*Ωignore_startΩ*/: ReturnType/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {
+ val;
+};return __sveltets_2_any(0)};
+;
+async () => {
+
+
+
+};
+return { props: /** @type {Record} */ ({}), exports: {}, bindings: "", slots: {}, events: {} }}
+const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(__sveltets_2_with_any_event($$render())));
+/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType;
+/*Ωignore_endΩ*/export default Input__SvelteComponent_;
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/snippet-generics.v5/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/snippet-generics.v5/input.svelte
new file mode 100644
index 000000000..4ee619728
--- /dev/null
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/snippet-generics.v5/input.svelte
@@ -0,0 +1,10 @@
+
+
+{#snippet generic(val: T)}
+ {val}
+{/snippet}
+
+{#snippet complex_generic">>(val: T)}
+ {val}
+{/snippet}
\ No newline at end of file
pFad - Phonifier reborn
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.