From f05d5315b830c99ac04adc1c21eb23e9ade9d7dc Mon Sep 17 00:00:00 2001 From: johnsoncodehk Date: Wed, 12 Oct 2022 00:23:21 +0800 Subject: [PATCH] feat: support intellisense for `generic` attribute close #1967 --- .../syntaxes/vue.tmLanguage.json | 53 +++++++++++++++++++ .../src/generators/script.ts | 17 +++++- .../vue-language-core/src/sourceFile.ts | 1 + .../vue-language-core/src/types.ts | 1 + 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/extensions/vscode-vue-language-features/syntaxes/vue.tmLanguage.json b/extensions/vscode-vue-language-features/syntaxes/vue.tmLanguage.json index c77ae1521..e5ebd4ff7 100644 --- a/extensions/vscode-vue-language-features/syntaxes/vue.tmLanguage.json +++ b/extensions/vscode-vue-language-features/syntaxes/vue.tmLanguage.json @@ -882,6 +882,9 @@ }, { "include": "#vue-directives-original" + }, + { + "include": "#vue-directives-generic-attr" } ] }, @@ -1085,6 +1088,56 @@ } ] }, + "vue-directives-generic-attr": { + "begin": "\\b(generic)\\s*(=)", + "captures": { + "1": { + "name": "entity.other.attribute-name.html.vue" + }, + "2": { + "name": "punctuation.separator.key-value.html.vue" + } + }, + "end": "(?<='|\")", + "name": "meta.attribute.generic.vue", + "patterns": [ + { + "begin": "('|\")", + "beginCaptures": { + "1": { + "name": "punctuation.definition.string.begin.html.vue" + } + }, + "end": "(\\1)", + "endCaptures": { + "1": { + "name": "punctuation.definition.string.end.html.vue" + } + }, + "name": "meta.type.parameters.vue", + "comment": "https://github.com/microsoft/vscode/blob/fd4346210f59135fad81a8b8c4cea7bf5a9ca6b4/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json#L4002-L4020", + "patterns": [ + { + "include": "source.ts#comment" + }, + { + "name": "storage.modifier.ts", + "match": "(?)" + } + ] + } + ] + }, "vue-interpolations": { "patterns": [ { diff --git a/vue-language-tools/vue-language-core/src/generators/script.ts b/vue-language-tools/vue-language-core/src/generators/script.ts index f66236d1f..880e70bbb 100644 --- a/vue-language-tools/vue-language-core/src/generators/script.ts +++ b/vue-language-tools/vue-language-core/src/generators/script.ts @@ -245,7 +245,22 @@ export function generate( codeGen.push('export default ('); } if (vueCompilerOptions.experimentalRfc436 && sfc.scriptSetup.generic) { - codeGen.push(`(<${sfc.scriptSetup.generic}>`); + codeGen.push(`(<`); + codeGen.push([ + sfc.scriptSetup.generic, + sfc.scriptSetup.name, + sfc.scriptSetup.genericOffset, + { + hover: true, + references: true, + definition: true, + rename: true, + diagnostic: true, + completion: true, + semanticTokens: true, + }, + ]); + codeGen.push(`>`); } codeGen.push('('); if (scriptSetupRanges.propsTypeArg) { diff --git a/vue-language-tools/vue-language-core/src/sourceFile.ts b/vue-language-tools/vue-language-core/src/sourceFile.ts index 44a135661..79d20c78c 100644 --- a/vue-language-tools/vue-language-core/src/sourceFile.ts +++ b/vue-language-tools/vue-language-core/src/sourceFile.ts @@ -449,6 +449,7 @@ export class VueSourceFile implements SourceFile { content: block.content, lang: block.lang ?? 'js', generic: typeof block.attrs.generic === 'string' ? block.attrs.generic : undefined, + genericOffset: typeof block.attrs.generic === 'string' ? newScriptSnapshot.getText(0, newScriptSnapshot.getLength()).substring(0, block.loc.start.offset).lastIndexOf(block.attrs.generic) - block.loc.start.offset : -1, } : null; if (self.sfc.scriptSetup && newData) { diff --git a/vue-language-tools/vue-language-core/src/types.ts b/vue-language-tools/vue-language-core/src/types.ts index 08240ce63..084fa552c 100644 --- a/vue-language-tools/vue-language-core/src/types.ts +++ b/vue-language-tools/vue-language-core/src/types.ts @@ -69,6 +69,7 @@ export interface Sfc { scriptSetup: SfcBlock & { // https://github.com/vuejs/rfcs/discussions/436 generic: string | undefined; + genericOffset: number; } | null; styles: (SfcBlock & { module: string | undefined;