@vue/language-service 2.0.14 → 2.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -688,7 +688,7 @@
688
688
  "valueSet": "v",
689
689
  "description": {
690
690
  "kind": "markdown",
691
- "value": "\n一个 `<style module>` 标签会被编译为 [CSS Modules](https://github.com/css-modules/css-modules) 并且将生成的 CSS class 作为 `$style` 对象暴露给组件:\n\n```vue\n<template>\n <p :class=\"$style.red\">This should be red</p>\n</template>\n\n<style module>\n.red {\n color: red;\n}\n</style>\n```\n\n得出的 class 将被哈希化以避免冲突,实现了同样的将 CSS 仅作用于当前组件的效果。\n\n参考 [CSS Modules spec](https://github.com/css-modules/css-modules) 以查看更多详情,例如 [global exceptions](https://github.com/css-modules/css-modules#exceptions) 和 [composition](https://github.com/css-modules/css-modules#composition)。\n\n### 自定义注入名称 \n\n你可以通过给 `module` attribute 一个值来自定义注入 class 对象的属性名:\n\n```vue\n<template>\n <p :class=\"classes.red\">red</p>\n</template>\n\n<style module=\"classes\">\n.red {\n color: red;\n}\n</style>\n```\n\n### 与组合式 API 一同使用 \n\n可以通过 `useCssModule` API 在 `setup()` 和 `<script setup>` 中访问注入的 class。对于使用了自定义注入名称的 `<style module>` 块,`useCssModule` 接收一个匹配的 `module` attribute 值作为第一个参数:\n\n```js\nimport { useCssModule } from 'vue'\n\n// 在 setup() 作用域中...\n// 默认情况下, 返回 <style module> 的 class\nuseCssModule()\n\n// 具名情况下, 返回 <style module=\"classes\"> 的 class\nuseCssModule('classes')\n```\n"
691
+ "value": "\n一个 `<style module>` 标签会被编译为 [CSS Modules](https://github.com/css-modules/css-modules) 并且将生成的 CSS class 作为 `$style` 对象暴露给组件:\n\n```vue\n<template>\n <p :class=\"$style.red\">This should be red</p>\n</template>\n\n<style module>\n.red {\n color: red;\n}\n</style>\n```\n\n得出的 class 将被哈希化以避免冲突,实现了同样的将 CSS 仅作用于当前组件的效果。\n\n参考 [CSS Modules spec](https://github.com/css-modules/css-modules) 以查看更多详情,例如 [global exceptions](https://github.com/css-modules/css-modules/blob/master/docs/composition.md#exceptions) 和 [composition](https://github.com/css-modules/css-modules/blob/master/docs/composition.md#composition)。\n\n### 自定义注入名称 \n\n你可以通过给 `module` attribute 一个值来自定义注入 class 对象的属性名:\n\n```vue\n<template>\n <p :class=\"classes.red\">red</p>\n</template>\n\n<style module=\"classes\">\n.red {\n color: red;\n}\n</style>\n```\n\n### 与组合式 API 一同使用 \n\n可以通过 `useCssModule` API 在 `setup()` 和 `<script setup>` 中访问注入的 class。对于使用了自定义注入名称的 `<style module>` 块,`useCssModule` 接收一个匹配的 `module` attribute 值作为第一个参数:\n\n```js\nimport { useCssModule } from 'vue'\n\n// 在 setup() 作用域中...\n// 默认情况下, 返回 <style module> 的 class\nuseCssModule()\n\n// 具名情况下, 返回 <style module=\"classes\"> 的 class\nuseCssModule('classes')\n```\n"
692
692
  },
693
693
  "references": [
694
694
  {
@@ -237,7 +237,7 @@
237
237
  "name": "Suspense",
238
238
  "description": {
239
239
  "kind": "markdown",
240
- "value": "\nUsed for orchestrating nested async dependencies in a component tree.\n\n- **Props**\n\n ```ts\n interface SuspenseProps {\n timeout?: string | number\n suspensible?: boolean\n }\n ```\n\n- **Events**\n\n - `@resolve`\n - `@pending`\n - `@fallback`\n\n- **Details**\n\n `<Suspense>` accepts two slots: the `#default` slot and the `#fallback` slot. It will display the content of the fallback slot while rendering the default slot in memory.\n\n If it encounters async dependencies ([Async Components](https://vuejs.org/guide/components/async.html) and components with [`async setup()`](https://vuejs.org/guide/built-ins/suspense.html#async-setup)) while rendering the default slot, it will wait until all of them are resolved before displaying the default slot.\n\n By setting the Suspense as `suspensible`, all the async dependency handling\n will be handled by the parent Suspense. See [implementation details](https://github.com/vuejs/core/pull/6736)\n\n- **See also** [Guide - Suspense](https://vuejs.org/guide/built-ins/suspense.html)\n"
240
+ "value": "\nUsed for orchestrating nested async dependencies in a component tree.\n\n- **Props**\n\n ```ts\n interface SuspenseProps {\n timeout?: string | number\n suspensible?: boolean\n }\n ```\n\n- **Events**\n\n - `@resolve`\n - `@pending`\n - `@fallback`\n\n- **Details**\n\n `<Suspense>` accepts two slots: the `#default` slot and the `#fallback` slot. It will display the content of the fallback slot while rendering the default slot in memory.\n\n If it encounters async dependencies ([Async Components](https://vuejs.org/guide/components/async.html) and components with [`async setup()`](https://vuejs.org/guide/built-ins/suspense.html#async-setup)) while rendering the default slot, it will wait until all of them are resolved before displaying the default slot.\n\n By setting the Suspense as `suspensible`, all the async dependency handling will be handled by the parent Suspense. See [implementation details](https://github.com/vuejs/core/pull/6736)\n\n- **See also** [Guide - Suspense](https://vuejs.org/guide/built-ins/suspense.html)\n"
241
241
  },
242
242
  "attributes": [],
243
243
  "references": [
@@ -1156,7 +1156,7 @@
1156
1156
  "name": "v-once",
1157
1157
  "description": {
1158
1158
  "kind": "markdown",
1159
- "value": "\nRender the element and component once only, and skip future updates.\n\n- **Does not expect expression**\n\n- **Details**\n\n On subsequent re-renders, the element/component and all its children will be treated as static content and skipped. This can be used to optimize update performance.\n\n ```html\n <!-- single element -->\n <span v-once>This will never change: {{msg}}</span>\n <!-- the element have children -->\n <div v-once>\n <h1>comment</h1>\n <p>{{msg}}</p>\n </div>\n <!-- component -->\n <MyComponent v-once :comment=\"msg\"></MyComponent>\n <!-- `v-for` directive -->\n <ul>\n <li v-for=\"i in list\" v-once>{{i}}</li>\n </ul>\n ```\n\n Since 3.2, you can also memoize part of the template with invalidation conditions using [`v-memo`](#v-memo).\n\n- **See also**\n - [Data Binding Syntax - interpolations](https://vuejs.org/guide/essentials/template-syntax.html#text-interpolation)\n - [v-memo](#v-memo)\n"
1159
+ "value": "\nRender the element and component once only, and skip future updates.\n\n- **Does not expect expression**\n\n- **Details**\n\n On subsequent re-renders, the element/component and all its children will be treated as static content and skipped. This can be used to optimize update performance.\n\n ```html\n <!-- single element -->\n <span v-once>This will never change: {{msg}}</span>\n <!-- the element have children -->\n <div v-once>\n <h1>Comment</h1>\n <p>{{msg}}</p>\n </div>\n <!-- component -->\n <MyComponent v-once :comment=\"msg\"></MyComponent>\n <!-- `v-for` directive -->\n <ul>\n <li v-for=\"i in list\" v-once>{{i}}</li>\n </ul>\n ```\n\n Since 3.2, you can also memoize part of the template with invalidation conditions using [`v-memo`](#v-memo).\n\n- **See also**\n - [Data Binding Syntax - interpolations](https://vuejs.org/guide/essentials/template-syntax.html#text-interpolation)\n - [v-memo](#v-memo)\n"
1160
1160
  },
1161
1161
  "references": [
1162
1162
  {
@@ -237,7 +237,7 @@
237
237
  "name": "Suspense",
238
238
  "description": {
239
239
  "kind": "markdown",
240
- "value": "\nUtilisé pour orchestrer des dépendances asynchrones imbriquées dans un arbre de composants.\n\n- **Props :**\n\n ```ts\n interface SuspenseProps {\n timeout?: string | number,\n suspensible?: boolean\n }\n ```\n\n- **Événements :**\n\n - `@resolve`\n - `@pending`\n - `@fallback`\n\n- **Détails**\n\n `<Suspense>` accepte deux slots : le slot `#default` et le slot `#fallback`. Il affichera le contenu du slot de secours tout en rendant le slot par défaut en mémoire.\n\n S'il rencontre des dépendances asynchrones ([Composants asynchrones](https://fr.vuejs.org/guide/components/async.html) et des composants avec [`async setup()`](https://fr.vuejs.org/guide/built-ins/suspense.html#async-setup)) lors du rendu du slot par défaut, il attendra qu'elles soient toutes résolues avant d'afficher le slot par défaut.\n\n En définissant Suspense comme `suspensible`, toutes les dépendances asynchrones seront gérées par le Suspense parent.\n Voir [les détails d'implémentation](https://github.com/vuejs/core/pull/6736)\n\n- **Voir aussi** [Guide - Suspense](https://fr.vuejs.org/guide/built-ins/suspense.html)\n"
240
+ "value": "\nUtilisé pour orchestrer des dépendances asynchrones imbriquées dans un arbre de composants.\n\n- **Props :**\n\n ```ts\n interface SuspenseProps {\n timeout?: string | number,\n suspensible?: boolean\n }\n ```\n\n- **Événements :**\n\n - `@resolve`\n - `@pending`\n - `@fallback`\n\n- **Détails**\n\n `<Suspense>` accepte deux slots : le slot `#default` et le slot `#fallback`. Il affichera le contenu du slot de secours tout en rendant le slot par défaut en mémoire.\n\n S'il rencontre des dépendances asynchrones ([Composants asynchrones](https://fr.vuejs.org/guide/components/async.html) et des composants avec [`async setup()`](https://fr.vuejs.org/guide/built-ins/suspense.html#async-setup)) lors du rendu du slot par défaut, il attendra qu'elles soient toutes résolues avant d'afficher le slot par défaut.\n\n En définissant Suspense comme `suspensible`, toutes les dépendances asynchrones seront gérées par le Suspense parent. Voir [les détails d'implémentation](https://github.com/vuejs/core/pull/6736)\n\n- **Voir aussi** [Guide - Suspense](https://fr.vuejs.org/guide/built-ins/suspense.html)\n"
241
241
  },
242
242
  "attributes": [],
243
243
  "references": [
@@ -237,7 +237,7 @@
237
237
  "name": "Suspense",
238
238
  "description": {
239
239
  "kind": "markdown",
240
- "value": "\nコンポーネントツリー内のネストした非同期な依存関係を管理するために使用します。\n\n- **props**\n\n ```ts\n interface SuspenseProps {\n timeout?: string | number\n suspensible?: boolean\n }\n ```\n\n- **イベント**\n\n - `@resolve`\n - `@pending`\n - `@fallback`\n\n- **詳細**\n\n `<Suspense>` は `#default` スロットと `#fallback` スロットの 2 つのスロットを受け付けます。default スロットをメモリー内にレンダリングする間、fallback スロットの内容を表示します。\n\n デフォルトスロットのレンダリング中に非同期な依存関係([非同期コンポーネント](https://ja.vuejs.org/guide/components/async.html)や [`async setup()`](https://ja.vuejs.org/guide/built-ins/suspense.html#async-setup) のコンポーネント)が発生すると、それらが全て解決するまで待ってからデフォルトスロットを表示します。\n\n Suspense を `suspensible` に設定することで、すべての非同期依存処理は親の Suspense によって処理されます。[実装の詳細](https://github.com/vuejs/core/pull/6736) を参照してください。\n\n\n- **参照** [ガイド - Suspense](https://ja.vuejs.org/guide/built-ins/suspense.html)\n"
240
+ "value": "\nコンポーネントツリー内のネストした非同期な依存関係を管理するために使用します。\n\n- **props**\n\n ```ts\n interface SuspenseProps {\n timeout?: string | number\n suspensible?: boolean\n }\n ```\n\n- **イベント**\n\n - `@resolve`\n - `@pending`\n - `@fallback`\n\n- **詳細**\n\n `<Suspense>` は `#default` スロットと `#fallback` スロットの 2 つのスロットを受け付けます。default スロットをメモリー内にレンダリングする間、fallback スロットの内容を表示します。\n\n デフォルトスロットのレンダリング中に非同期な依存関係([非同期コンポーネント](https://ja.vuejs.org/guide/components/async.html)や [`async setup()`](https://ja.vuejs.org/guide/built-ins/suspense.html#async-setup) のコンポーネント)が発生すると、それらが全て解決するまで待ってからデフォルトスロットを表示します。\n\n Suspense を `suspensible` に設定することで、すべての非同期依存処理は親の Suspense によって処理されます。[実装の詳細](https://github.com/vuejs/core/pull/6736) を参照してください。\n\n- **参照** [ガイド - Suspense](https://ja.vuejs.org/guide/built-ins/suspense.html)\n"
241
241
  },
242
242
  "attributes": [],
243
243
  "references": [
package/index.d.ts CHANGED
@@ -4,5 +4,5 @@ export * from './lib/ideFeatures/nameCasing';
4
4
  export * from './lib/types';
5
5
  import type { ServiceContext, ServiceEnvironment, LanguageServicePlugin } from '@volar/language-service';
6
6
  import type { VueCompilerOptions } from './lib/types';
7
- export declare function createVueServicePlugins(ts: typeof import('typescript'), getVueOptions: (env: ServiceEnvironment) => VueCompilerOptions, getTsPluginClient?: (context: ServiceContext) => typeof import("@vue/typescript-plugin/lib/client") | undefined, hybridMode?: boolean): LanguageServicePlugin[];
7
+ export declare function getVueLanguageServicePlugins(ts: typeof import('typescript'), getVueOptions: (env: ServiceEnvironment) => VueCompilerOptions, getTsPluginClient?: (context: ServiceContext) => typeof import("@vue/typescript-plugin/lib/client") | undefined, hybridMode?: boolean): LanguageServicePlugin[];
8
8
  export declare function createDefaultGetTsPluginClient(ts: typeof import('typescript'), getVueOptions: (env: ServiceEnvironment) => VueCompilerOptions): (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined;
package/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.createDefaultGetTsPluginClient = exports.createVueServicePlugins = void 0;
17
+ exports.createDefaultGetTsPluginClient = exports.getVueLanguageServicePlugins = void 0;
18
18
  __exportStar(require("@volar/language-service"), exports);
19
19
  __exportStar(require("@vue/language-core"), exports);
20
20
  __exportStar(require("./lib/ideFeatures/nameCasing"), exports);
@@ -45,7 +45,7 @@ const componentInfos_1 = require("@vue/typescript-plugin/lib/requests/componentI
45
45
  const getImportPathForFile_1 = require("@vue/typescript-plugin/lib/requests/getImportPathForFile");
46
46
  const getPropertiesAtLocation_1 = require("@vue/typescript-plugin/lib/requests/getPropertiesAtLocation");
47
47
  const getQuickInfoAtPosition_1 = require("@vue/typescript-plugin/lib/requests/getQuickInfoAtPosition");
48
- function createVueServicePlugins(ts, getVueOptions, getTsPluginClient = createDefaultGetTsPluginClient(ts, getVueOptions), hybridMode = false) {
48
+ function getVueLanguageServicePlugins(ts, getVueOptions, getTsPluginClient = createDefaultGetTsPluginClient(ts, getVueOptions), hybridMode = false) {
49
49
  const plugins = [];
50
50
  if (!hybridMode) {
51
51
  plugins.push(...(0, volar_service_typescript_1.create)(ts));
@@ -72,10 +72,15 @@ function createVueServicePlugins(ts, getVueOptions, getTsPluginClient = createDe
72
72
  else {
73
73
  plugins.push((0, syntactic_1.create)(ts), (0, docCommentTemplate_1.create)(ts));
74
74
  }
75
- plugins.push((0, volar_service_typescript_twoslash_queries_1.create)(ts), (0, css_1.create)(), (0, volar_service_pug_beautify_1.create)(), (0, volar_service_json_1.create)(), (0, vue_template_1.create)('html', ts, getVueOptions, getTsPluginClient), (0, vue_template_1.create)('pug', ts, getVueOptions, getTsPluginClient), (0, vue_sfc_1.create)(), (0, vue_twoslash_queries_1.create)(ts, getTsPluginClient), (0, vue_codelens_references_1.create)(), (0, vue_document_drop_1.create)(ts, getTsPluginClient), (0, vue_autoinsert_dotvalue_1.create)(ts, getTsPluginClient), (0, vue_autoinsert_parentheses_1.create)(ts), (0, vue_autoinsert_space_1.create)(), (0, vue_visualize_hidden_callback_param_1.create)(), (0, vue_directive_comments_1.create)(), (0, vue_extract_file_1.create)(ts, getTsPluginClient), (0, vue_toggle_v_bind_codeaction_1.create)(ts), (0, volar_service_emmet_1.create)());
75
+ plugins.push((0, volar_service_typescript_twoslash_queries_1.create)(ts), (0, css_1.create)(), (0, volar_service_pug_beautify_1.create)(), (0, volar_service_json_1.create)(), (0, vue_template_1.create)('html', ts, getVueOptions, getTsPluginClient), (0, vue_template_1.create)('pug', ts, getVueOptions, getTsPluginClient), (0, vue_sfc_1.create)(), (0, vue_twoslash_queries_1.create)(ts, getTsPluginClient), (0, vue_codelens_references_1.create)(), (0, vue_document_drop_1.create)(ts, getTsPluginClient), (0, vue_autoinsert_dotvalue_1.create)(ts, getTsPluginClient), (0, vue_autoinsert_parentheses_1.create)(ts), (0, vue_autoinsert_space_1.create)(), (0, vue_visualize_hidden_callback_param_1.create)(), (0, vue_directive_comments_1.create)(), (0, vue_extract_file_1.create)(ts, getTsPluginClient), (0, vue_toggle_v_bind_codeaction_1.create)(ts), (0, volar_service_emmet_1.create)({
76
+ mappedModes: {
77
+ 'vue': 'html',
78
+ 'postcss': 'scss',
79
+ },
80
+ }));
76
81
  return plugins;
77
82
  }
78
- exports.createVueServicePlugins = createVueServicePlugins;
83
+ exports.getVueLanguageServicePlugins = getVueLanguageServicePlugins;
79
84
  function createDefaultGetTsPluginClient(ts, getVueOptions) {
80
85
  return context => {
81
86
  if (!context.language.typescript) {
@@ -3,11 +3,11 @@ import type * as vscode from 'vscode-languageserver-protocol';
3
3
  import { AttrNameCasing, TagNameCasing } from '../types';
4
4
  export declare function convertTagName(context: ServiceContext, uri: string, casing: TagNameCasing, tsPluginClient: typeof import('@vue/typescript-plugin/lib/client') | undefined): Promise<vscode.TextEdit[] | undefined>;
5
5
  export declare function convertAttrName(context: ServiceContext, uri: string, casing: AttrNameCasing, tsPluginClient?: typeof import('@vue/typescript-plugin/lib/client')): Promise<vscode.TextEdit[] | undefined>;
6
- export declare function getNameCasing(context: ServiceContext, uri: string, tsPluginClient?: typeof import('@vue/typescript-plugin/lib/client')): Promise<{
6
+ export declare function getNameCasing(context: ServiceContext, uri: string): Promise<{
7
7
  tag: TagNameCasing;
8
8
  attr: AttrNameCasing;
9
9
  }>;
10
- export declare function detect(context: ServiceContext, uri: string, tsPluginClient?: typeof import('@vue/typescript-plugin/lib/client')): Promise<{
10
+ export declare function detect(context: ServiceContext, uri: string): Promise<{
11
11
  tag: TagNameCasing[];
12
12
  attr: AttrNameCasing[];
13
13
  }>;
@@ -85,8 +85,8 @@ async function convertAttrName(context, uri, casing, tsPluginClient) {
85
85
  return edits;
86
86
  }
87
87
  exports.convertAttrName = convertAttrName;
88
- async function getNameCasing(context, uri, tsPluginClient) {
89
- const detected = await detect(context, uri, tsPluginClient);
88
+ async function getNameCasing(context, uri) {
89
+ const detected = await detect(context, uri);
90
90
  const [attr, tag] = await Promise.all([
91
91
  context.env.getConfiguration?.('vue.complete.casing.props', uri),
92
92
  context.env.getConfiguration?.('vue.complete.casing.tags', uri),
@@ -99,7 +99,7 @@ async function getNameCasing(context, uri, tsPluginClient) {
99
99
  };
100
100
  }
101
101
  exports.getNameCasing = getNameCasing;
102
- async function detect(context, uri, tsPluginClient) {
102
+ async function detect(context, uri) {
103
103
  const rootFile = context.language.scripts.get(uri)?.generated?.root;
104
104
  if (!(rootFile instanceof language_core_1.VueVirtualCode)) {
105
105
  return {
@@ -133,35 +133,23 @@ async function detect(context, uri, tsPluginClient) {
133
133
  return result;
134
134
  }
135
135
  async function getTagNameCase(file) {
136
- const components = await tsPluginClient?.getComponentNames(file.fileName) ?? [];
137
- const tagNames = getTemplateTagsAndAttrs(file);
138
- const result = [];
139
- let anyComponentUsed = false;
140
- for (const component of components) {
141
- if (tagNames.has(component) || tagNames.has((0, language_core_1.hyphenateTag)(component))) {
142
- anyComponentUsed = true;
143
- break;
144
- }
145
- }
146
- if (!anyComponentUsed) {
147
- return []; // not sure component style, because do not have any component using in <template> for check
148
- }
149
- for (const [tagName] of tagNames) {
150
- // TagName
151
- if (tagName !== (0, language_core_1.hyphenateTag)(tagName)) {
152
- result.push(types_1.TagNameCasing.Pascal);
153
- break;
154
- }
155
- }
156
- for (const component of components) {
157
- // Tagname -> tagname
158
- // TagName -> tag-name
159
- if (component !== (0, language_core_1.hyphenateTag)(component) && tagNames.has((0, language_core_1.hyphenateTag)(component))) {
160
- result.push(types_1.TagNameCasing.Kebab);
161
- break;
136
+ const result = new Set();
137
+ if (file.sfc.template?.ast) {
138
+ for (const element of vue.forEachElementNode(file.sfc.template.ast)) {
139
+ if (element.tagType === 1) {
140
+ if (element.tag !== (0, language_core_1.hyphenateTag)(element.tag)) {
141
+ // TagName
142
+ result.add(types_1.TagNameCasing.Pascal);
143
+ }
144
+ else {
145
+ // Tagname -> tagname
146
+ // TagName -> tag-name
147
+ result.add(types_1.TagNameCasing.Kebab);
148
+ }
149
+ }
162
150
  }
163
151
  }
164
- return result;
152
+ return [...result];
165
153
  }
166
154
  }
167
155
  exports.detect = detect;
@@ -16,6 +16,7 @@ let modelData;
16
16
  function create(mode, ts, getVueOptions, getTsPluginClient) {
17
17
  let customData = [];
18
18
  let extraCustomData = [];
19
+ let lastCompletionComponentNames = new Set();
19
20
  const onDidChangeCustomDataListeners = new Set();
20
21
  const onDidChangeCustomData = (listener) => {
21
22
  onDidChangeCustomDataListeners.add(listener);
@@ -92,6 +93,8 @@ function create(mode, ts, getVueOptions, getTsPluginClient) {
92
93
  const decoded = context.decodeEmbeddedDocumentUri(document.uri);
93
94
  const sourceScript = decoded && context.language.scripts.get(decoded[0]);
94
95
  if (sourceScript?.generated?.root instanceof language_core_1.VueVirtualCode) {
96
+ // #4298: Precompute HTMLDocument before provideHtmlData to avoid parseHTMLDocument requesting component names from tsserver
97
+ baseServiceInstance.provideCompletionItems?.(document, position, completionContext, token);
95
98
  sync = (await provideHtmlData(sourceScript.id, sourceScript.generated.root)).sync;
96
99
  currentVersion = await sync();
97
100
  }
@@ -103,7 +106,7 @@ function create(mode, ts, getVueOptions, getTsPluginClient) {
103
106
  return;
104
107
  }
105
108
  if (sourceScript?.generated?.root instanceof language_core_1.VueVirtualCode) {
106
- await afterHtmlCompletion(htmlComplete, context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot), sourceScript.generated.root);
109
+ await afterHtmlCompletion(htmlComplete, context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot));
107
110
  }
108
111
  return htmlComplete;
109
112
  },
@@ -127,7 +130,7 @@ function create(mode, ts, getVueOptions, getTsPluginClient) {
127
130
  const scanner = getScanner(baseServiceInstance, document);
128
131
  if (code instanceof language_core_1.VueVirtualCode && scanner) {
129
132
  // visualize missing required props
130
- const casing = await (0, nameCasing_1.getNameCasing)(context, map.sourceDocument.uri, tsPluginClient);
133
+ const casing = await (0, nameCasing_1.getNameCasing)(context, map.sourceDocument.uri);
131
134
  const components = await tsPluginClient?.getComponentNames(code.fileName) ?? [];
132
135
  const componentProps = {};
133
136
  let token;
@@ -135,10 +138,9 @@ function create(mode, ts, getVueOptions, getTsPluginClient) {
135
138
  while ((token = scanner.scan()) !== html.TokenType.EOS) {
136
139
  if (token === html.TokenType.StartTag) {
137
140
  const tagName = scanner.getTokenText();
138
- const component = tagName.indexOf('.') >= 0
139
- ? components.find(component => component === tagName.split('.')[0])
141
+ const checkTag = tagName.indexOf('.') >= 0
142
+ ? tagName
140
143
  : components.find(component => component === tagName || (0, language_core_1.hyphenateTag)(component) === tagName);
141
- const checkTag = tagName.indexOf('.') >= 0 ? tagName : component;
142
144
  if (checkTag) {
143
145
  componentProps[checkTag] ??= await tsPluginClient?.getComponentProps(code.fileName, checkTag, true) ?? [];
144
146
  current = {
@@ -310,7 +312,7 @@ function create(mode, ts, getVueOptions, getTsPluginClient) {
310
312
  };
311
313
  async function provideHtmlData(sourceDocumentUri, vueCode) {
312
314
  await (initializing ??= initialize());
313
- const casing = await (0, nameCasing_1.getNameCasing)(context, sourceDocumentUri, tsPluginClient);
315
+ const casing = await (0, nameCasing_1.getNameCasing)(context, sourceDocumentUri);
314
316
  if (builtInData.tags) {
315
317
  for (const tag of builtInData.tags) {
316
318
  if (tag.name === 'slot') {
@@ -349,6 +351,7 @@ function create(mode, ts, getVueOptions, getTsPluginClient) {
349
351
  && name !== 'KeepAlive'
350
352
  && name !== 'Suspense'
351
353
  && name !== 'Teleport');
354
+ lastCompletionComponentNames = new Set(components);
352
355
  version++;
353
356
  })());
354
357
  return [];
@@ -503,10 +506,8 @@ function create(mode, ts, getVueOptions, getTsPluginClient) {
503
506
  }
504
507
  };
505
508
  }
506
- async function afterHtmlCompletion(completionList, sourceDocument, code) {
509
+ async function afterHtmlCompletion(completionList, sourceDocument) {
507
510
  const replacement = getReplacement(completionList, sourceDocument);
508
- const componentNames = new Set((await tsPluginClient?.getComponentNames(code.fileName) ?? [])
509
- .map(language_core_1.hyphenateTag));
510
511
  if (replacement) {
511
512
  const isEvent = replacement.text.startsWith('v-on:') || replacement.text.startsWith('@');
512
513
  const isProp = replacement.text.startsWith('v-bind:') || replacement.text.startsWith(':');
@@ -570,7 +571,7 @@ function create(mode, ts, getVueOptions, getTsPluginClient) {
570
571
  if (itemId) {
571
572
  item.documentation = undefined;
572
573
  }
573
- if (item.kind === 10 && componentNames.has((0, language_core_1.hyphenateTag)(item.label))) {
574
+ if (item.kind === 10 && lastCompletionComponentNames.has((0, language_core_1.hyphenateTag)(item.label))) {
574
575
  item.kind = 6;
575
576
  item.sortText = '\u0000' + (item.sortText ?? item.label);
576
577
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/language-service",
3
- "version": "2.0.14",
3
+ "version": "2.0.16",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "data",
@@ -16,32 +16,32 @@
16
16
  "update-html-data": "node ./scripts/update-html-data.js"
17
17
  },
18
18
  "dependencies": {
19
- "@volar/language-core": "2.2.0-alpha.10",
20
- "@volar/language-service": "2.2.0-alpha.10",
21
- "@volar/typescript": "2.2.0-alpha.10",
19
+ "@volar/language-core": "~2.2.0",
20
+ "@volar/language-service": "~2.2.0",
21
+ "@volar/typescript": "~2.2.0",
22
22
  "@vue/compiler-dom": "^3.4.0",
23
- "@vue/language-core": "2.0.14",
23
+ "@vue/language-core": "2.0.16",
24
24
  "@vue/shared": "^3.4.0",
25
- "@vue/typescript-plugin": "2.0.14",
25
+ "@vue/typescript-plugin": "2.0.16",
26
26
  "computeds": "^0.0.1",
27
27
  "path-browserify": "^1.0.1",
28
- "volar-service-css": "0.0.38",
29
- "volar-service-emmet": "0.0.38",
30
- "volar-service-html": "0.0.38",
31
- "volar-service-json": "0.0.38",
32
- "volar-service-pug": "0.0.38",
33
- "volar-service-pug-beautify": "0.0.38",
34
- "volar-service-typescript": "0.0.38",
35
- "volar-service-typescript-twoslash-queries": "0.0.38",
36
- "vscode-html-languageservice": "^5.1.0",
28
+ "volar-service-css": "0.0.42",
29
+ "volar-service-emmet": "0.0.42",
30
+ "volar-service-html": "0.0.42",
31
+ "volar-service-json": "0.0.42",
32
+ "volar-service-pug": "0.0.42",
33
+ "volar-service-pug-beautify": "0.0.42",
34
+ "volar-service-typescript": "0.0.42",
35
+ "volar-service-typescript-twoslash-queries": "0.0.42",
36
+ "vscode-html-languageservice": "npm:@johnsoncodehk/vscode-html-languageservice@5.2.0-34a5462",
37
37
  "vscode-languageserver-textdocument": "^1.0.11",
38
38
  "vscode-uri": "^3.0.8"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/node": "latest",
42
42
  "@types/path-browserify": "latest",
43
- "@volar/kit": "2.2.0-alpha.10",
43
+ "@volar/kit": "~2.2.0",
44
44
  "vscode-languageserver-protocol": "^3.17.5"
45
45
  },
46
- "gitHead": "ce1412067f88b7f9af03a2d3e04c220b4921c363"
46
+ "gitHead": "95b78c38cbf75481ebb59e11956b592346f01d92"
47
47
  }