@vue/language-service 2.0.6 → 2.0.10

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.
Files changed (34) hide show
  1. package/data/language-blocks/en.json +1 -1
  2. package/data/model-modifiers/ja.json +1 -1
  3. package/data/template/ja.json +1 -1
  4. package/index.d.ts +3 -2
  5. package/index.js +88 -23
  6. package/lib/ideFeatures/nameCasing.d.ts +2 -2
  7. package/lib/ideFeatures/nameCasing.js +23 -16
  8. package/lib/plugins/css.d.ts +2 -2
  9. package/lib/plugins/data.js +6 -3
  10. package/lib/plugins/vue-autoinsert-dotvalue.d.ts +5 -5
  11. package/lib/plugins/vue-autoinsert-dotvalue.js +37 -31
  12. package/lib/plugins/vue-autoinsert-parentheses.d.ts +2 -2
  13. package/lib/plugins/vue-autoinsert-parentheses.js +15 -6
  14. package/lib/plugins/vue-autoinsert-space.d.ts +2 -2
  15. package/lib/plugins/vue-autoinsert-space.js +7 -14
  16. package/lib/plugins/vue-codelens-references.d.ts +2 -2
  17. package/lib/plugins/vue-codelens-references.js +8 -4
  18. package/lib/plugins/vue-directive-comments.d.ts +2 -2
  19. package/lib/plugins/vue-directive-comments.js +4 -3
  20. package/lib/plugins/vue-document-drop.d.ts +2 -2
  21. package/lib/plugins/vue-document-drop.js +36 -14
  22. package/lib/plugins/vue-extract-file.d.ts +2 -2
  23. package/lib/plugins/vue-extract-file.js +32 -18
  24. package/lib/plugins/vue-sfc.d.ts +2 -2
  25. package/lib/plugins/vue-sfc.js +40 -35
  26. package/lib/plugins/vue-template.d.ts +3 -3
  27. package/lib/plugins/vue-template.js +86 -32
  28. package/lib/plugins/vue-toggle-v-bind-codeaction.d.ts +2 -2
  29. package/lib/plugins/vue-toggle-v-bind-codeaction.js +6 -3
  30. package/lib/plugins/vue-twoslash-queries.d.ts +2 -2
  31. package/lib/plugins/vue-twoslash-queries.js +9 -5
  32. package/lib/plugins/vue-visualize-hidden-callback-param.d.ts +2 -2
  33. package/lib/plugins/vue-visualize-hidden-callback-param.js +7 -4
  34. package/package.json +19 -19
@@ -556,7 +556,7 @@
556
556
  "valueSet": "v",
557
557
  "description": {
558
558
  "kind": "markdown",
559
- "value": "\nA `<style module>` tag is compiled as [CSS Modules](https://github.com/css-modules/css-modules) and exposes the resulting CSS classes to the component as an object under the key of `$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\nThe resulting classes are hashed to avoid collision, achieving the same effect of scoping the CSS to the current component only.\n\nRefer to the [CSS Modules spec](https://github.com/css-modules/css-modules) for more details such as [global exceptions](https://github.com/css-modules/css-modules#exceptions) and [composition](https://github.com/css-modules/css-modules#composition).\n\n### Custom Inject Name \n\nYou can customize the property key of the injected classes object by giving the `module` attribute a value:\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### Usage with Composition API \n\nThe injected classes can be accessed in `setup()` and `<script setup>` via the `useCssModule` API. For `<style module>` blocks with custom injection names, `useCssModule` accepts the matching `module` attribute value as the first argument:\n\n```js\nimport { useCssModule } from 'vue'\n\n// inside setup() scope...\n// default, returns classes for <style module>\nuseCssModule()\n\n// named, returns classes for <style module=\"classes\">\nuseCssModule('classes')\n```\n"
559
+ "value": "\nA `<style module>` tag is compiled as [CSS Modules](https://github.com/css-modules/css-modules) and exposes the resulting CSS classes to the component as an object under the key of `$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\nThe resulting classes are hashed to avoid collision, achieving the same effect of scoping the CSS to the current component only.\n\nRefer to the [CSS Modules spec](https://github.com/css-modules/css-modules) for more details such as [global exceptions](https://github.com/css-modules/css-modules/blob/master/docs/composition.md#exceptions) and [composition](https://github.com/css-modules/css-modules/blob/master/docs/composition.md#composition).\n\n### Custom Inject Name \n\nYou can customize the property key of the injected classes object by giving the `module` attribute a value:\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### Usage with Composition API \n\nThe injected classes can be accessed in `setup()` and `<script setup>` via the `useCssModule` API. For `<style module>` blocks with custom injection names, `useCssModule` accepts the matching `module` attribute value as the first argument:\n\n```js\nimport { useCssModule } from 'vue'\n\n// inside setup() scope...\n// default, returns classes for <style module>\nuseCssModule()\n\n// named, returns classes for <style module=\"classes\">\nuseCssModule('classes')\n```\n"
560
560
  },
561
561
  "references": [
562
562
  {
@@ -5,7 +5,7 @@
5
5
  "name": "lazy",
6
6
  "description": {
7
7
  "kind": "markdown",
8
- "value": "\nデフォルトでは、 `v-model` は各 `input` イベントの後に、入力とデータを同期します ([上記](#vmodel-ime-tip) の IME による入力は例外とします)。 代わりに `change` イベント後に同期する `lazy` 修飾子を追加することができます。\n\n```html\n<!-- \"input\" の代わりに \"change\" イベント後に同期されます -->\n<input v-model.lazy=\"msg\" />\n```\n"
8
+ "value": "\nデフォルトでは、 `v-model` は各 `input` イベントの後に、入力とデータを同期します([上記](#vmodel-ime-tip) の IME による入力は例外とします)。 代わりに `change` イベント後に同期する `lazy` 修飾子を追加することができます。\n\n```html\n<!-- \"input\" の代わりに \"change\" イベント後に同期されます -->\n<input v-model.lazy=\"msg\" />\n```\n"
9
9
  },
10
10
  "references": [
11
11
  {
@@ -736,7 +736,7 @@
736
736
  "name": "v-bind",
737
737
  "description": {
738
738
  "kind": "markdown",
739
- "value": "\n1 つ以上の属性やコンポーネントの props を式に動的にバインドします。\n\n- **省略記法:**\n - `:` or `.`(`.prop` 修飾子使用時)\n - 値の省略(属性とバインドされた値が同じ名前の場合)<sup class=\"vt-badge\">3.4+</sup>\n\n- **期待する値:** `any(引数ありの場合) | Object(引数なしの場合)`\n\n- **引数:** `attrOrProp(省略可能)`\n\n- **修飾子**\n\n - `.camel` - kebab-case の属性名を camelCase に変換します。\n - `.prop` - バインディングを DOM プロパティとして設定するよう強制します。<sup class=\"vt-badge\">3.2+</sup>\n - `.attr` - バインディングを DOM 属性として設定するよう強制します。<sup class=\"vt-badge\">3.2+</sup>\n\n- **使用法**\n\n `class` や `style` 属性をバインドする際に使用する `v-bind` は、Array や Object などの追加の値の型をサポートします。詳しくは、以下のリンク先のガイドを参照してください。\n\n 要素にバインディングを設定するとき、Vue はデフォルトで、`in` 演算子チェックを使用して、プロパティとして定義されたキーが要素にあるかどうかを確認します。プロパティが定義されている場合、Vue はその値を属性ではなく DOM プロパティとして設定します。これはほとんどの場合において有効ですが、`.prop` や `.attr` という修飾子を明示的に使用することでこの動作をオーバーライドできます。これは、特に[カスタム要素を扱う](https://ja.vuejs.org/guide/extras/web-components.html#passing-dom-properties)ときに必要になることがあります。\n\n コンポーネントの props をバインドするために使用する場合、その props は子コンポーネントで適切に宣言されている必要があります。\n\n 引数なしで使用する場合、属性の名前と値のペアを含むオブジェクトをバインドするために使用できます。\n\n- **例**\n\n ```html\n <!-- 属性をバインドする -->\n <img v-bind:src=\"imageSrc\" />\n\n <!-- 動的な属性名 -->\n <button v-bind:[key]=\"value\"></button>\n\n <!-- 省略記法 -->\n <img :src=\"imageSrc\" />\n\n <!-- 同名省略記法 (3.4+), :src=\"src\" のように展開する -->\n <img :src />\n\n <!-- 動的な属性名の省略記法 -->\n <button :[key]=\"value\"></button>\n\n <!-- インラインの文字列連結 -->\n <img :src=\"'/path/to/images/' + fileName\" />\n\n <!-- クラスのバインド -->\n <div :class=\"{ red: isRed }\"></div>\n <div :class=\"[classA, classB]\"></div>\n <div :class=\"[classA, { classB: isB, classC: isC }]\"></div>\n\n <!-- スタイルのバインド -->\n <div :style=\"{ fontSize: size + 'px' }\"></div>\n <div :style=\"[styleObjectA, styleObjectB]\"></div>\n\n <!-- 属性のオブジェクトをバインド -->\n <div v-bind=\"{ id: someProp, 'other-attr': otherProp }\"></div>\n\n <!-- props のバインド。\"prop\" は子コンポーネントで宣言する必要があります。 -->\n <MyComponent :prop=\"someThing\" />\n\n <!-- 親の props を子コンポーネントと共有するために渡す -->\n <MyComponent v-bind=\"$props\" />\n\n <!-- XLink -->\n <svg><a :xlink:special=\"foo\"></a></svg>\n ```\n\n `.prop` 修飾子には、専用の短縮形 `.` もあります:\n\n ```html\n <div :someProperty.prop=\"someObject\"></div>\n\n <!-- 以下と同じ -->\n <div .someProperty=\"someObject\"></div>\n ```\n\n `.camel` 修飾子は、DOM 内テンプレートを使用する際に、 `v-bind` 属性名をキャメル化できます(例: SVG の `viewBox` 属性):\n\n ```html\n <svg :view-box.camel=\"viewBox\"></svg>\n ```\n\n 文字列テンプレートを使用する場合や、ビルドステップでテンプレートを事前コンパイルする場合は、`.camel` は必要ありません。\n\n- **参照**\n - [クラスとスタイルのバインディング](https://ja.vuejs.org/guide/essentials/class-and-style.html)\n - [コンポーネント - props 渡しの詳細](https://ja.vuejs.org/guide/components/props.html#prop-passing-details)\n"
739
+ "value": "\n1 つ以上の属性やコンポーネントの props を式に動的にバインドします。\n\n- **省略記法:**\n - `:` or `.`(`.prop` 修飾子使用時)\n - 値の省略(属性とバインドされた値が同じ名前の場合)<sup class=\"vt-badge\">3.4+</sup>\n\n- **期待する値:** `any(引数ありの場合)| Object(引数なしの場合)`\n\n- **引数:** `attrOrProp(省略可能)`\n\n- **修飾子**\n\n - `.camel` - kebab-case の属性名を camelCase に変換します。\n - `.prop` - バインディングを DOM プロパティとして設定するよう強制します。<sup class=\"vt-badge\">3.2+</sup>\n - `.attr` - バインディングを DOM 属性として設定するよう強制します。<sup class=\"vt-badge\">3.2+</sup>\n\n- **使用法**\n\n `class` や `style` 属性をバインドする際に使用する `v-bind` は、Array や Object などの追加の値の型をサポートします。詳しくは、以下のリンク先のガイドを参照してください。\n\n 要素にバインディングを設定するとき、Vue はデフォルトで、`in` 演算子チェックを使用して、プロパティとして定義されたキーが要素にあるかどうかを確認します。プロパティが定義されている場合、Vue はその値を属性ではなく DOM プロパティとして設定します。これはほとんどの場合において有効ですが、`.prop` や `.attr` という修飾子を明示的に使用することでこの動作をオーバーライドできます。これは、特に[カスタム要素を扱う](https://ja.vuejs.org/guide/extras/web-components.html#passing-dom-properties)ときに必要になることがあります。\n\n コンポーネントの props をバインドするために使用する場合、その props は子コンポーネントで適切に宣言されている必要があります。\n\n 引数なしで使用する場合、属性の名前と値のペアを含むオブジェクトをバインドするために使用できます。\n\n- **例**\n\n ```html\n <!-- 属性をバインドする -->\n <img v-bind:src=\"imageSrc\" />\n\n <!-- 動的な属性名 -->\n <button v-bind:[key]=\"value\"></button>\n\n <!-- 省略記法 -->\n <img :src=\"imageSrc\" />\n\n <!-- 同名省略記法(3.4+), :src=\"src\" のように展開する -->\n <img :src />\n\n <!-- 動的な属性名の省略記法 -->\n <button :[key]=\"value\"></button>\n\n <!-- インラインの文字列連結 -->\n <img :src=\"'/path/to/images/' + fileName\" />\n\n <!-- クラスのバインド -->\n <div :class=\"{ red: isRed }\"></div>\n <div :class=\"[classA, classB]\"></div>\n <div :class=\"[classA, { classB: isB, classC: isC }]\"></div>\n\n <!-- スタイルのバインド -->\n <div :style=\"{ fontSize: size + 'px' }\"></div>\n <div :style=\"[styleObjectA, styleObjectB]\"></div>\n\n <!-- 属性のオブジェクトをバインド -->\n <div v-bind=\"{ id: someProp, 'other-attr': otherProp }\"></div>\n\n <!-- props のバインド。\"prop\" は子コンポーネントで宣言する必要があります。 -->\n <MyComponent :prop=\"someThing\" />\n\n <!-- 親の props を子コンポーネントと共有するために渡す -->\n <MyComponent v-bind=\"$props\" />\n\n <!-- XLink -->\n <svg><a :xlink:special=\"foo\"></a></svg>\n ```\n\n `.prop` 修飾子には、専用の短縮形 `.` もあります:\n\n ```html\n <div :someProperty.prop=\"someObject\"></div>\n\n <!-- 以下と同じ -->\n <div .someProperty=\"someObject\"></div>\n ```\n\n `.camel` 修飾子は、DOM 内テンプレートを使用する際に、 `v-bind` 属性名をキャメル化できます(例: SVG の `viewBox` 属性):\n\n ```html\n <svg :view-box.camel=\"viewBox\"></svg>\n ```\n\n 文字列テンプレートを使用する場合や、ビルドステップでテンプレートを事前コンパイルする場合は、`.camel` は必要ありません。\n\n- **参照**\n - [クラスとスタイルのバインディング](https://ja.vuejs.org/guide/essentials/class-and-style.html)\n - [コンポーネント - props 渡しの詳細](https://ja.vuejs.org/guide/components/props.html#prop-passing-details)\n"
740
740
  },
741
741
  "references": [
742
742
  {
package/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from '@volar/language-service';
2
2
  export * from '@vue/language-core';
3
3
  export * from './lib/ideFeatures/nameCasing';
4
4
  export * from './lib/types';
5
- import type { ServiceEnvironment, ServicePlugin } from '@volar/language-service';
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, tsPluginClient?: typeof import('@vue/typescript-plugin/lib/client')): ServicePlugin[];
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[];
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.createVueServicePlugins = void 0;
17
+ exports.createDefaultGetTsPluginClient = exports.createVueServicePlugins = 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);
@@ -24,6 +24,8 @@ const volar_service_json_1 = require("volar-service-json");
24
24
  const volar_service_pug_beautify_1 = require("volar-service-pug-beautify");
25
25
  const volar_service_typescript_1 = require("volar-service-typescript");
26
26
  const volar_service_typescript_twoslash_queries_1 = require("volar-service-typescript-twoslash-queries");
27
+ const docCommentTemplate_1 = require("volar-service-typescript/lib/plugins/docCommentTemplate");
28
+ const syntactic_1 = require("volar-service-typescript/lib/plugins/syntactic");
27
29
  const css_1 = require("./lib/plugins/css");
28
30
  const vue_autoinsert_dotvalue_1 = require("./lib/plugins/vue-autoinsert-dotvalue");
29
31
  const vue_autoinsert_parentheses_1 = require("./lib/plugins/vue-autoinsert-parentheses");
@@ -37,28 +39,91 @@ const vue_template_1 = require("./lib/plugins/vue-template");
37
39
  const vue_toggle_v_bind_codeaction_1 = require("./lib/plugins/vue-toggle-v-bind-codeaction");
38
40
  const vue_twoslash_queries_1 = require("./lib/plugins/vue-twoslash-queries");
39
41
  const vue_visualize_hidden_callback_param_1 = require("./lib/plugins/vue-visualize-hidden-callback-param");
40
- function createVueServicePlugins(ts, getVueOptions, tsPluginClient) {
41
- return [
42
- (0, volar_service_typescript_1.create)(ts),
43
- (0, volar_service_typescript_twoslash_queries_1.create)(),
44
- (0, css_1.create)(),
45
- (0, volar_service_pug_beautify_1.create)(),
46
- (0, volar_service_json_1.create)(),
47
- (0, vue_template_1.create)('html', ts, getVueOptions, tsPluginClient),
48
- (0, vue_template_1.create)('pug', ts, getVueOptions, tsPluginClient),
49
- (0, vue_sfc_1.create)(),
50
- (0, vue_twoslash_queries_1.create)(ts, tsPluginClient),
51
- (0, vue_codelens_references_1.create)(),
52
- (0, vue_document_drop_1.create)(ts),
53
- (0, vue_autoinsert_dotvalue_1.create)(ts, tsPluginClient),
54
- (0, vue_autoinsert_parentheses_1.create)(ts),
55
- (0, vue_autoinsert_space_1.create)(),
56
- (0, vue_visualize_hidden_callback_param_1.create)(),
57
- (0, vue_directive_comments_1.create)(),
58
- (0, vue_extract_file_1.create)(ts, tsPluginClient),
59
- (0, vue_toggle_v_bind_codeaction_1.create)(ts),
60
- (0, volar_service_emmet_1.create)(),
61
- ];
42
+ const common_1 = require("@vue/typescript-plugin/lib/common");
43
+ const collectExtractProps_1 = require("@vue/typescript-plugin/lib/requests/collectExtractProps");
44
+ const componentInfos_1 = require("@vue/typescript-plugin/lib/requests/componentInfos");
45
+ const getImportPathForFile_1 = require("@vue/typescript-plugin/lib/requests/getImportPathForFile");
46
+ const getPropertiesAtLocation_1 = require("@vue/typescript-plugin/lib/requests/getPropertiesAtLocation");
47
+ const getQuickInfoAtPosition_1 = require("@vue/typescript-plugin/lib/requests/getQuickInfoAtPosition");
48
+ function createVueServicePlugins(ts, getVueOptions, getTsPluginClient = createDefaultGetTsPluginClient(ts, getVueOptions), hybridMode = false) {
49
+ const plugins = [];
50
+ if (!hybridMode) {
51
+ plugins.push(...(0, volar_service_typescript_1.create)(ts));
52
+ for (let i = 0; i < plugins.length; i++) {
53
+ const plugin = plugins[i];
54
+ if (plugin.name === 'typescript-semantic') {
55
+ plugins[i] = {
56
+ ...plugin,
57
+ create(context) {
58
+ const created = plugin.create(context);
59
+ if (!context.language.typescript) {
60
+ return created;
61
+ }
62
+ const languageService = created.provide['typescript/languageService']();
63
+ const vueOptions = getVueOptions(context.env);
64
+ (0, common_1.decorateLanguageServiceForVue)(context.language, languageService, vueOptions, ts, false);
65
+ return created;
66
+ },
67
+ };
68
+ break;
69
+ }
70
+ }
71
+ }
72
+ else {
73
+ plugins.push((0, syntactic_1.create)(ts), (0, docCommentTemplate_1.create)(ts));
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)());
76
+ return plugins;
62
77
  }
63
78
  exports.createVueServicePlugins = createVueServicePlugins;
79
+ function createDefaultGetTsPluginClient(ts, getVueOptions) {
80
+ return context => {
81
+ if (!context.language.typescript) {
82
+ return;
83
+ }
84
+ const languageService = context.inject('typescript/languageService');
85
+ if (!languageService) {
86
+ return;
87
+ }
88
+ const requestContext = {
89
+ typescript: ts,
90
+ language: context.language,
91
+ languageService,
92
+ languageServiceHost: context.language.typescript.languageServiceHost,
93
+ vueOptions: getVueOptions(context.env),
94
+ isTsPlugin: false,
95
+ getFileId: context.env.typescript.fileNameToUri,
96
+ };
97
+ return {
98
+ async collectExtractProps(...args) {
99
+ return await collectExtractProps_1.collectExtractProps.apply(requestContext, args);
100
+ },
101
+ async getPropertiesAtLocation(...args) {
102
+ return await getPropertiesAtLocation_1.getPropertiesAtLocation.apply(requestContext, args);
103
+ },
104
+ async getImportPathForFile(...args) {
105
+ return await getImportPathForFile_1.getImportPathForFile.apply(requestContext, args);
106
+ },
107
+ async getComponentEvents(...args) {
108
+ return await componentInfos_1.getComponentEvents.apply(requestContext, args);
109
+ },
110
+ async getComponentNames(...args) {
111
+ return await componentInfos_1.getComponentNames.apply(requestContext, args);
112
+ },
113
+ async getComponentProps(...args) {
114
+ return await componentInfos_1.getComponentProps.apply(requestContext, args);
115
+ },
116
+ async getElementAttrs(...args) {
117
+ return await componentInfos_1.getElementAttrs.apply(requestContext, args);
118
+ },
119
+ async getTemplateContextProps(...args) {
120
+ return await componentInfos_1.getTemplateContextProps.apply(requestContext, args);
121
+ },
122
+ async getQuickInfoAtPosition(...args) {
123
+ return await getQuickInfoAtPosition_1.getQuickInfoAtPosition.apply(requestContext, args);
124
+ },
125
+ };
126
+ };
127
+ }
128
+ exports.createDefaultGetTsPluginClient = createDefaultGetTsPluginClient;
64
129
  //# sourceMappingURL=index.js.map
@@ -1,8 +1,8 @@
1
1
  import type { ServiceContext } from '@volar/language-service';
2
2
  import type * as vscode from 'vscode-languageserver-protocol';
3
3
  import { AttrNameCasing, TagNameCasing } from '../types';
4
- export declare function convertTagName(context: ServiceContext, uri: string, casing: TagNameCasing, tsPluginClient: typeof import('@vue/typescript-plugin/lib/client')): Promise<vscode.TextEdit[] | undefined>;
5
- export declare function convertAttrName(context: ServiceContext, uri: string, casing: AttrNameCasing, tsPluginClient: typeof import('@vue/typescript-plugin/lib/client')): Promise<vscode.TextEdit[] | undefined>;
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
+ export declare function convertAttrName(context: ServiceContext, uri: string, casing: AttrNameCasing, tsPluginClient?: typeof import('@vue/typescript-plugin/lib/client')): Promise<vscode.TextEdit[] | undefined>;
6
6
  export declare function getNameCasing(context: ServiceContext, uri: string, tsPluginClient?: typeof import('@vue/typescript-plugin/lib/client')): Promise<{
7
7
  tag: TagNameCasing;
8
8
  attr: AttrNameCasing;
@@ -6,19 +6,22 @@ const language_core_1 = require("@vue/language-core");
6
6
  const computeds_1 = require("computeds");
7
7
  const types_1 = require("../types");
8
8
  async function convertTagName(context, uri, casing, tsPluginClient) {
9
- const sourceFile = context.language.files.get(uri);
10
- if (!sourceFile)
9
+ const sourceFile = context.language.scripts.get(uri);
10
+ if (!sourceFile) {
11
11
  return;
12
- const rootCode = sourceFile?.generated?.code;
13
- if (!(rootCode instanceof language_core_1.VueGeneratedCode))
12
+ }
13
+ const rootCode = sourceFile?.generated?.root;
14
+ if (!(rootCode instanceof language_core_1.VueGeneratedCode)) {
14
15
  return;
16
+ }
15
17
  const desc = rootCode.sfc;
16
- if (!desc.template)
18
+ if (!desc.template) {
17
19
  return;
20
+ }
18
21
  const template = desc.template;
19
22
  const document = context.documents.get(sourceFile.id, sourceFile.languageId, sourceFile.snapshot);
20
23
  const edits = [];
21
- const components = await tsPluginClient.getComponentNames(rootCode.fileName) ?? [];
24
+ const components = await tsPluginClient?.getComponentNames(rootCode.fileName) ?? [];
22
25
  const tags = getTemplateTagsAndAttrs(rootCode);
23
26
  for (const [tagName, { offsets }] of tags) {
24
27
  const componentName = components.find(component => component === tagName || (0, language_core_1.hyphenateTag)(component) === tagName);
@@ -40,24 +43,27 @@ async function convertTagName(context, uri, casing, tsPluginClient) {
40
43
  }
41
44
  exports.convertTagName = convertTagName;
42
45
  async function convertAttrName(context, uri, casing, tsPluginClient) {
43
- const sourceFile = context.language.files.get(uri);
44
- if (!sourceFile)
46
+ const sourceFile = context.language.scripts.get(uri);
47
+ if (!sourceFile) {
45
48
  return;
46
- const rootCode = sourceFile?.generated?.code;
47
- if (!(rootCode instanceof language_core_1.VueGeneratedCode))
49
+ }
50
+ const rootCode = sourceFile?.generated?.root;
51
+ if (!(rootCode instanceof language_core_1.VueGeneratedCode)) {
48
52
  return;
53
+ }
49
54
  const desc = rootCode.sfc;
50
- if (!desc.template)
55
+ if (!desc.template) {
51
56
  return;
57
+ }
52
58
  const template = desc.template;
53
59
  const document = context.documents.get(uri, sourceFile.languageId, sourceFile.snapshot);
54
60
  const edits = [];
55
- const components = await tsPluginClient.getComponentNames(rootCode.fileName) ?? [];
61
+ const components = await tsPluginClient?.getComponentNames(rootCode.fileName) ?? [];
56
62
  const tags = getTemplateTagsAndAttrs(rootCode);
57
63
  for (const [tagName, { attrs }] of tags) {
58
64
  const componentName = components.find(component => component === tagName || (0, language_core_1.hyphenateTag)(component) === tagName);
59
65
  if (componentName) {
60
- const props = await tsPluginClient.getComponentProps(rootCode.fileName, componentName) ?? [];
66
+ const props = await tsPluginClient?.getComponentProps(rootCode.fileName, componentName) ?? [];
61
67
  for (const [attrName, { offsets }] of attrs) {
62
68
  const propName = props.find(prop => prop === attrName || (0, language_core_1.hyphenateAttr)(prop) === attrName);
63
69
  if (propName) {
@@ -94,7 +100,7 @@ async function getNameCasing(context, uri, tsPluginClient) {
94
100
  }
95
101
  exports.getNameCasing = getNameCasing;
96
102
  async function detect(context, uri, tsPluginClient) {
97
- const rootFile = context.language.files.get(uri)?.generated?.code;
103
+ const rootFile = context.language.scripts.get(uri)?.generated?.root;
98
104
  if (!(rootFile instanceof language_core_1.VueGeneratedCode)) {
99
105
  return {
100
106
  tag: [],
@@ -163,12 +169,13 @@ const map = new WeakMap();
163
169
  function getTemplateTagsAndAttrs(sourceFile) {
164
170
  if (!map.has(sourceFile)) {
165
171
  const getter = (0, computeds_1.computed)(() => {
166
- if (!(sourceFile instanceof vue.VueGeneratedCode))
172
+ if (!(sourceFile instanceof vue.VueGeneratedCode)) {
167
173
  return;
174
+ }
168
175
  const ast = sourceFile.sfc.template?.ast;
169
176
  const tags = new Map();
170
177
  if (ast) {
171
- for (const node of vue.eachElementNode(ast)) {
178
+ for (const node of vue.forEachElementNode(ast)) {
172
179
  if (!tags.has(node.tag)) {
173
180
  tags.set(node.tag, { offsets: [], attrs: new Map() });
174
181
  }
@@ -1,2 +1,2 @@
1
- import type { ServicePlugin } from '@volar/language-service';
2
- export declare function create(): ServicePlugin;
1
+ import type { LanguageServicePlugin } from '@volar/language-service';
2
+ export declare function create(): LanguageServicePlugin;
@@ -33,12 +33,15 @@ function loadTemplateData(lang) {
33
33
  const vOn = data.globalAttributes?.find(d => d.name === 'v-on');
34
34
  const vSlot = data.globalAttributes?.find(d => d.name === 'v-slot');
35
35
  const vBind = data.globalAttributes?.find(d => d.name === 'v-bind');
36
- if (vOn)
36
+ if (vOn) {
37
37
  data.globalAttributes?.push({ ...vOn, name: '@' });
38
- if (vSlot)
38
+ }
39
+ if (vSlot) {
39
40
  data.globalAttributes?.push({ ...vSlot, name: '#' });
40
- if (vBind)
41
+ }
42
+ if (vBind) {
41
43
  data.globalAttributes?.push({ ...vBind, name: ':' });
44
+ }
42
45
  return data;
43
46
  }
44
47
  exports.loadTemplateData = loadTemplateData;
@@ -1,10 +1,10 @@
1
- import type { ServicePlugin } from '@volar/language-service';
1
+ import type { ServiceContext, LanguageServicePlugin } from '@volar/language-service';
2
2
  import type * as ts from 'typescript';
3
- import type * as vscode from 'vscode-languageserver-protocol';
4
3
  import type { TextDocument } from 'vscode-languageserver-textdocument';
5
- export declare function create(ts: typeof import('typescript'), tsPluginClient?: typeof import('@vue/typescript-plugin/lib/client')): ServicePlugin;
6
- export declare function isCharacterTyping(document: TextDocument, lastChange: {
7
- range: vscode.Range;
4
+ export declare function create(ts: typeof import('typescript'), getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined): LanguageServicePlugin;
5
+ export declare function isCharacterTyping(document: TextDocument, change: {
8
6
  text: string;
7
+ rangeOffset: number;
8
+ rangeLength: number;
9
9
  }): boolean;
10
10
  export declare function isBlacklistNode(ts: typeof import('typescript'), node: ts.Node, pos: number, allowAccessDotValue: boolean): boolean;
@@ -11,40 +11,52 @@ function getAst(ts, fileName, snapshot, scriptKind) {
11
11
  }
12
12
  return ast;
13
13
  }
14
- function create(ts, tsPluginClient) {
14
+ function create(ts, getTsPluginClient) {
15
15
  return {
16
16
  name: 'vue-autoinsert-dotvalue',
17
17
  create(context) {
18
+ const tsPluginClient = getTsPluginClient?.(context);
18
19
  let currentReq = 0;
19
20
  return {
20
- async provideAutoInsertionEdit(document, position, lastChange) {
21
- if (!isTsDocument(document))
21
+ async provideAutoInsertionEdit(document, selection, change) {
22
+ // selection must at end of change
23
+ if (document.offsetAt(selection) !== change.rangeOffset + change.text.length) {
22
24
  return;
23
- if (!isCharacterTyping(document, lastChange))
25
+ }
26
+ if (!isTsDocument(document)) {
27
+ return;
28
+ }
29
+ if (!isCharacterTyping(document, change)) {
24
30
  return;
31
+ }
25
32
  const req = ++currentReq;
26
33
  // Wait for tsserver to sync
27
34
  await sleep(250);
28
- if (req !== currentReq)
35
+ if (req !== currentReq) {
29
36
  return;
37
+ }
30
38
  const enabled = await context.env.getConfiguration?.('vue.autoInsert.dotValue') ?? true;
31
- if (!enabled)
39
+ if (!enabled) {
32
40
  return;
33
- const [code, file] = context.documents.getVirtualCodeByUri(document.uri);
34
- if (!file)
41
+ }
42
+ const decoded = context.decodeEmbeddedDocumentUri(document.uri);
43
+ const sourceScript = decoded && context.language.scripts.get(decoded[0]);
44
+ const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
45
+ if (!sourceScript) {
35
46
  return;
47
+ }
36
48
  let ast;
37
- let sourceCodeOffset = document.offsetAt(position);
38
- const fileName = context.env.typescript.uriToFileName(file.id);
39
- if (file?.generated) {
40
- const script = file.generated.languagePlugin.typescript?.getScript(file.generated.code);
41
- if (script?.code !== code) {
49
+ let sourceCodeOffset = document.offsetAt(selection);
50
+ const fileName = context.env.typescript.uriToFileName(sourceScript.id);
51
+ if (sourceScript.generated) {
52
+ const serviceScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(sourceScript.generated.root);
53
+ if (!serviceScript || serviceScript?.code !== virtualCode) {
42
54
  return;
43
55
  }
44
- ast = getAst(ts, fileName, script.code.snapshot, script.scriptKind);
56
+ ast = getAst(ts, fileName, virtualCode.snapshot, serviceScript.scriptKind);
45
57
  let mapped = false;
46
- for (const [_1, [_2, map]] of context.language.files.getMaps(code)) {
47
- const sourceOffset = map.getSourceOffset(document.offsetAt(position));
58
+ for (const [_1, [_2, map]] of context.language.maps.forEach(virtualCode)) {
59
+ const sourceOffset = map.getSourceOffset(document.offsetAt(selection));
48
60
  if (sourceOffset !== undefined) {
49
61
  sourceCodeOffset = sourceOffset[0];
50
62
  mapped = true;
@@ -56,10 +68,11 @@ function create(ts, tsPluginClient) {
56
68
  }
57
69
  }
58
70
  else {
59
- ast = getAst(ts, fileName, file.snapshot);
71
+ ast = getAst(ts, fileName, sourceScript.snapshot);
60
72
  }
61
- if (isBlacklistNode(ts, ast, document.offsetAt(position), false))
73
+ if (isBlacklistNode(ts, ast, document.offsetAt(selection), false)) {
62
74
  return;
75
+ }
63
76
  const props = await tsPluginClient?.getPropertiesAtLocation(fileName, sourceCodeOffset) ?? [];
64
77
  if (props.some(prop => prop === 'value')) {
65
78
  return '${1:.value}';
@@ -80,21 +93,13 @@ function isTsDocument(document) {
80
93
  document.languageId === 'typescriptreact';
81
94
  }
82
95
  const charReg = /\w/;
83
- function isCharacterTyping(document, lastChange) {
84
- const lastCharacter = lastChange.text[lastChange.text.length - 1];
85
- const rangeStart = lastChange.range.start;
86
- const position = {
87
- line: rangeStart.line,
88
- character: rangeStart.character + lastChange.text.length,
89
- };
90
- const nextCharacter = document.getText({
91
- start: position,
92
- end: { line: position.line, character: position.character + 1 },
93
- });
96
+ function isCharacterTyping(document, change) {
97
+ const lastCharacter = change.text[change.text.length - 1];
98
+ const nextCharacter = document.getText().substring(change.rangeOffset + change.text.length, change.rangeOffset + change.text.length + 1);
94
99
  if (lastCharacter === undefined) { // delete text
95
100
  return false;
96
101
  }
97
- if (lastChange.text.indexOf('\n') >= 0) { // multi-line change
102
+ if (change.text.indexOf('\n') >= 0) { // multi-line change
98
103
  return false;
99
104
  }
100
105
  return charReg.test(lastCharacter) && !charReg.test(nextCharacter);
@@ -137,8 +142,9 @@ function isBlacklistNode(ts, node, pos, allowAccessDotValue) {
137
142
  else {
138
143
  let _isBlacklistNode = false;
139
144
  node.forEachChild(node => {
140
- if (_isBlacklistNode)
145
+ if (_isBlacklistNode) {
141
146
  return;
147
+ }
142
148
  if (pos >= node.getFullStart() && pos <= node.getEnd()) {
143
149
  if (isBlacklistNode(ts, node, pos, allowAccessDotValue)) {
144
150
  _isBlacklistNode = true;
@@ -1,2 +1,2 @@
1
- import type { ServicePlugin } from '@volar/language-service';
2
- export declare function create(ts: typeof import('typescript')): ServicePlugin;
1
+ import type { LanguageServicePlugin } from '@volar/language-service';
2
+ export declare function create(ts: typeof import('typescript')): LanguageServicePlugin;
@@ -7,16 +7,25 @@ function create(ts) {
7
7
  name: 'vue-autoinsert-parentheses',
8
8
  create(context) {
9
9
  return {
10
- async provideAutoInsertionEdit(document, position, lastChange) {
10
+ async provideAutoInsertionEdit(document, selection, change) {
11
+ // selection must at end of change
12
+ if (document.offsetAt(selection) !== change.rangeOffset + change.text.length) {
13
+ return;
14
+ }
11
15
  const enabled = await context.env.getConfiguration?.('vue.autoInsert.parentheses') ?? false;
12
- if (!enabled)
16
+ if (!enabled) {
13
17
  return;
14
- if (!(0, vue_autoinsert_dotvalue_1.isCharacterTyping)(document, lastChange))
18
+ }
19
+ if (!(0, vue_autoinsert_dotvalue_1.isCharacterTyping)(document, change)) {
15
20
  return;
16
- const [virtualCode] = context.documents.getVirtualCodeByUri(document.uri);
17
- if (virtualCode?.id !== 'template_format')
21
+ }
22
+ const decoded = context.decodeEmbeddedDocumentUri(document.uri);
23
+ const sourceScript = decoded && context.language.scripts.get(decoded[0]);
24
+ const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
25
+ if (!virtualCode?.id.startsWith('template_inline_ts_')) {
18
26
  return;
19
- const offset = document.offsetAt(position);
27
+ }
28
+ const offset = document.offsetAt(selection);
20
29
  for (const mappedRange of virtualCode.mappings) {
21
30
  const generatedCodeEnd = mappedRange.generatedOffsets[mappedRange.generatedOffsets.length - 1]
22
31
  + mappedRange.lengths[mappedRange.lengths.length - 1];
@@ -1,2 +1,2 @@
1
- import type { ServicePlugin } from '@volar/language-service';
2
- export declare function create(): ServicePlugin;
1
+ import type { LanguageServicePlugin } from '@volar/language-service';
2
+ export declare function create(): LanguageServicePlugin;
@@ -6,23 +6,16 @@ function create() {
6
6
  name: 'vue-autoinsert-space',
7
7
  create(context) {
8
8
  return {
9
- async provideAutoInsertionEdit(document, _, lastChange) {
9
+ async provideAutoInsertionEdit(document, selection, change) {
10
10
  if (document.languageId === 'html' || document.languageId === 'jade') {
11
11
  const enabled = await context.env.getConfiguration?.('vue.autoInsert.bracketSpacing') ?? true;
12
- if (!enabled)
12
+ if (!enabled) {
13
13
  return;
14
- if (lastChange.text === '{}'
15
- && document.getText({
16
- start: { line: lastChange.range.start.line, character: lastChange.range.start.character - 1 },
17
- end: { line: lastChange.range.start.line, character: lastChange.range.start.character + 3 }
18
- }) === '{{}}') {
19
- return {
20
- newText: ` $0 `,
21
- range: {
22
- start: { line: lastChange.range.start.line, character: lastChange.range.start.character + 1 },
23
- end: { line: lastChange.range.start.line, character: lastChange.range.start.character + 1 }
24
- },
25
- };
14
+ }
15
+ if (change.text === '{}'
16
+ && document.getText().substring(change.rangeOffset - 1, change.rangeOffset + 3) === '{{}}'
17
+ && document.offsetAt(selection) === change.rangeOffset + 1) {
18
+ return ` $0 `;
26
19
  }
27
20
  }
28
21
  },
@@ -1,2 +1,2 @@
1
- import type { ServicePlugin } from '@volar/language-service';
2
- export declare function create(): ServicePlugin;
1
+ import type { LanguageServicePlugin } from '@volar/language-service';
2
+ export declare function create(): LanguageServicePlugin;
@@ -12,8 +12,9 @@ function create() {
12
12
  const result = [];
13
13
  for (const map of context.documents.getMaps(virtualCode) ?? []) {
14
14
  for (const mapping of map.map.mappings) {
15
- if (!mapping.data.__referencesCodeLens)
15
+ if (!mapping.data.__referencesCodeLens) {
16
16
  continue;
17
+ }
17
18
  result.push({
18
19
  start: document.positionAt(mapping.generatedOffsets[0]),
19
20
  end: document.positionAt(mapping.generatedOffsets[mapping.generatedOffsets.length - 1]
@@ -26,10 +27,13 @@ function create() {
26
27
  },
27
28
  };
28
29
  function worker(uri, callback) {
29
- const [virtualCode, sourceFile] = context.documents.getVirtualCodeByUri(uri);
30
- if (!(sourceFile?.generated?.code instanceof language_core_1.VueGeneratedCode) || !sourceFile)
30
+ const decoded = context.decodeEmbeddedDocumentUri(uri);
31
+ const sourceScript = decoded && context.language.scripts.get(decoded[0]);
32
+ const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
33
+ if (!virtualCode || !(sourceScript?.generated?.root instanceof language_core_1.VueGeneratedCode) || !sourceScript) {
31
34
  return;
32
- return callback(virtualCode, sourceFile);
35
+ }
36
+ return callback(virtualCode, sourceScript);
33
37
  }
34
38
  },
35
39
  };
@@ -1,2 +1,2 @@
1
- import type { ServicePlugin } from '@volar/language-service';
2
- export declare function create(): ServicePlugin;
1
+ import type { LanguageServicePlugin } from '@volar/language-service';
2
+ export declare function create(): LanguageServicePlugin;
@@ -14,12 +14,14 @@ function create() {
14
14
  create() {
15
15
  return {
16
16
  provideCompletionItems(document, position) {
17
- if (document.languageId !== 'html')
17
+ if (document.languageId !== 'html') {
18
18
  return;
19
+ }
19
20
  const line = document.getText({ start: { line: position.line, character: 0 }, end: position });
20
21
  const cmdStart = line.match(directiveCommentReg);
21
- if (!cmdStart)
22
+ if (!cmdStart) {
22
23
  return;
24
+ }
23
25
  const startIndex = cmdStart.index + cmdStart[0].length;
24
26
  const remainText = line.substring(startIndex);
25
27
  const result = [];
@@ -27,7 +29,6 @@ function create() {
27
29
  let match = true;
28
30
  for (let i = 0; i < remainText.length; i++) {
29
31
  if (remainText[i] !== cmd[i]) {
30
- console.log(JSON.stringify(remainText[i]), JSON.stringify(cmd[i]));
31
32
  match = false;
32
33
  break;
33
34
  }
@@ -1,2 +1,2 @@
1
- import { ServicePlugin } from '../types';
2
- export declare function create(ts: typeof import('typescript')): ServicePlugin;
1
+ import { LanguageServicePlugin, ServiceContext } from '../types';
2
+ export declare function create(ts: typeof import('typescript'), getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined): LanguageServicePlugin;