@vue/language-service 2.0.7 → 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.
- package/data/language-blocks/en.json +1 -1
- package/data/model-modifiers/ja.json +1 -1
- package/data/template/ja.json +1 -1
- package/index.d.ts +2 -2
- package/index.js +13 -5
- package/lib/ideFeatures/nameCasing.js +6 -6
- package/lib/plugins/css.d.ts +2 -2
- package/lib/plugins/vue-autoinsert-dotvalue.d.ts +5 -5
- package/lib/plugins/vue-autoinsert-dotvalue.js +24 -26
- package/lib/plugins/vue-autoinsert-parentheses.d.ts +2 -2
- package/lib/plugins/vue-autoinsert-parentheses.js +11 -5
- package/lib/plugins/vue-autoinsert-space.d.ts +2 -2
- package/lib/plugins/vue-autoinsert-space.js +5 -13
- package/lib/plugins/vue-codelens-references.d.ts +2 -2
- package/lib/plugins/vue-codelens-references.js +5 -3
- package/lib/plugins/vue-directive-comments.d.ts +2 -2
- package/lib/plugins/vue-document-drop.d.ts +2 -2
- package/lib/plugins/vue-document-drop.js +29 -11
- package/lib/plugins/vue-extract-file.d.ts +2 -2
- package/lib/plugins/vue-extract-file.js +14 -10
- package/lib/plugins/vue-sfc.d.ts +2 -2
- package/lib/plugins/vue-sfc.js +29 -28
- package/lib/plugins/vue-template.d.ts +2 -2
- package/lib/plugins/vue-template.js +28 -18
- package/lib/plugins/vue-toggle-v-bind-codeaction.d.ts +2 -2
- package/lib/plugins/vue-toggle-v-bind-codeaction.js +4 -2
- package/lib/plugins/vue-twoslash-queries.d.ts +2 -2
- package/lib/plugins/vue-twoslash-queries.js +6 -4
- package/lib/plugins/vue-visualize-hidden-callback-param.d.ts +2 -2
- package/lib/plugins/vue-visualize-hidden-callback-param.js +5 -3
- package/package.json +16 -16
|
@@ -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`
|
|
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
|
{
|
package/data/template/ja.json
CHANGED
|
@@ -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
|
|
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,7 +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 { ServiceContext, ServiceEnvironment,
|
|
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):
|
|
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
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
|
@@ -42,6 +42,7 @@ const vue_visualize_hidden_callback_param_1 = require("./lib/plugins/vue-visuali
|
|
|
42
42
|
const common_1 = require("@vue/typescript-plugin/lib/common");
|
|
43
43
|
const collectExtractProps_1 = require("@vue/typescript-plugin/lib/requests/collectExtractProps");
|
|
44
44
|
const componentInfos_1 = require("@vue/typescript-plugin/lib/requests/componentInfos");
|
|
45
|
+
const getImportPathForFile_1 = require("@vue/typescript-plugin/lib/requests/getImportPathForFile");
|
|
45
46
|
const getPropertiesAtLocation_1 = require("@vue/typescript-plugin/lib/requests/getPropertiesAtLocation");
|
|
46
47
|
const getQuickInfoAtPosition_1 = require("@vue/typescript-plugin/lib/requests/getQuickInfoAtPosition");
|
|
47
48
|
function createVueServicePlugins(ts, getVueOptions, getTsPluginClient = createDefaultGetTsPluginClient(ts, getVueOptions), hybridMode = false) {
|
|
@@ -60,7 +61,7 @@ function createVueServicePlugins(ts, getVueOptions, getTsPluginClient = createDe
|
|
|
60
61
|
}
|
|
61
62
|
const languageService = created.provide['typescript/languageService']();
|
|
62
63
|
const vueOptions = getVueOptions(context.env);
|
|
63
|
-
(0, common_1.decorateLanguageServiceForVue)(context.language
|
|
64
|
+
(0, common_1.decorateLanguageServiceForVue)(context.language, languageService, vueOptions, ts, false);
|
|
64
65
|
return created;
|
|
65
66
|
},
|
|
66
67
|
};
|
|
@@ -71,7 +72,7 @@ function createVueServicePlugins(ts, getVueOptions, getTsPluginClient = createDe
|
|
|
71
72
|
else {
|
|
72
73
|
plugins.push((0, syntactic_1.create)(ts), (0, docCommentTemplate_1.create)(ts));
|
|
73
74
|
}
|
|
74
|
-
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), (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)());
|
|
75
76
|
return plugins;
|
|
76
77
|
}
|
|
77
78
|
exports.createVueServicePlugins = createVueServicePlugins;
|
|
@@ -80,10 +81,15 @@ function createDefaultGetTsPluginClient(ts, getVueOptions) {
|
|
|
80
81
|
if (!context.language.typescript) {
|
|
81
82
|
return;
|
|
82
83
|
}
|
|
84
|
+
const languageService = context.inject('typescript/languageService');
|
|
85
|
+
if (!languageService) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
83
88
|
const requestContext = {
|
|
84
89
|
typescript: ts,
|
|
85
|
-
|
|
86
|
-
languageService
|
|
90
|
+
language: context.language,
|
|
91
|
+
languageService,
|
|
92
|
+
languageServiceHost: context.language.typescript.languageServiceHost,
|
|
87
93
|
vueOptions: getVueOptions(context.env),
|
|
88
94
|
isTsPlugin: false,
|
|
89
95
|
getFileId: context.env.typescript.fileNameToUri,
|
|
@@ -95,6 +101,9 @@ function createDefaultGetTsPluginClient(ts, getVueOptions) {
|
|
|
95
101
|
async getPropertiesAtLocation(...args) {
|
|
96
102
|
return await getPropertiesAtLocation_1.getPropertiesAtLocation.apply(requestContext, args);
|
|
97
103
|
},
|
|
104
|
+
async getImportPathForFile(...args) {
|
|
105
|
+
return await getImportPathForFile_1.getImportPathForFile.apply(requestContext, args);
|
|
106
|
+
},
|
|
98
107
|
async getComponentEvents(...args) {
|
|
99
108
|
return await componentInfos_1.getComponentEvents.apply(requestContext, args);
|
|
100
109
|
},
|
|
@@ -115,7 +124,6 @@ function createDefaultGetTsPluginClient(ts, getVueOptions) {
|
|
|
115
124
|
},
|
|
116
125
|
};
|
|
117
126
|
};
|
|
118
|
-
;
|
|
119
127
|
}
|
|
120
128
|
exports.createDefaultGetTsPluginClient = createDefaultGetTsPluginClient;
|
|
121
129
|
//# sourceMappingURL=index.js.map
|
|
@@ -6,11 +6,11 @@ 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.
|
|
9
|
+
const sourceFile = context.language.scripts.get(uri);
|
|
10
10
|
if (!sourceFile) {
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
|
-
const rootCode = sourceFile?.generated?.
|
|
13
|
+
const rootCode = sourceFile?.generated?.root;
|
|
14
14
|
if (!(rootCode instanceof language_core_1.VueGeneratedCode)) {
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
@@ -43,11 +43,11 @@ async function convertTagName(context, uri, casing, tsPluginClient) {
|
|
|
43
43
|
}
|
|
44
44
|
exports.convertTagName = convertTagName;
|
|
45
45
|
async function convertAttrName(context, uri, casing, tsPluginClient) {
|
|
46
|
-
const sourceFile = context.language.
|
|
46
|
+
const sourceFile = context.language.scripts.get(uri);
|
|
47
47
|
if (!sourceFile) {
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
|
-
const rootCode = sourceFile?.generated?.
|
|
50
|
+
const rootCode = sourceFile?.generated?.root;
|
|
51
51
|
if (!(rootCode instanceof language_core_1.VueGeneratedCode)) {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
@@ -100,7 +100,7 @@ async function getNameCasing(context, uri, tsPluginClient) {
|
|
|
100
100
|
}
|
|
101
101
|
exports.getNameCasing = getNameCasing;
|
|
102
102
|
async function detect(context, uri, tsPluginClient) {
|
|
103
|
-
const rootFile = context.language.
|
|
103
|
+
const rootFile = context.language.scripts.get(uri)?.generated?.root;
|
|
104
104
|
if (!(rootFile instanceof language_core_1.VueGeneratedCode)) {
|
|
105
105
|
return {
|
|
106
106
|
tag: [],
|
|
@@ -175,7 +175,7 @@ function getTemplateTagsAndAttrs(sourceFile) {
|
|
|
175
175
|
const ast = sourceFile.sfc.template?.ast;
|
|
176
176
|
const tags = new Map();
|
|
177
177
|
if (ast) {
|
|
178
|
-
for (const node of vue.
|
|
178
|
+
for (const node of vue.forEachElementNode(ast)) {
|
|
179
179
|
if (!tags.has(node.tag)) {
|
|
180
180
|
tags.set(node.tag, { offsets: [], attrs: new Map() });
|
|
181
181
|
}
|
package/lib/plugins/css.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function create():
|
|
1
|
+
import type { LanguageServicePlugin } from '@volar/language-service';
|
|
2
|
+
export declare function create(): LanguageServicePlugin;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { ServiceContext,
|
|
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'), getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined):
|
|
6
|
-
export declare function isCharacterTyping(document: TextDocument,
|
|
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;
|
|
@@ -18,11 +18,15 @@ function create(ts, getTsPluginClient) {
|
|
|
18
18
|
const tsPluginClient = getTsPluginClient?.(context);
|
|
19
19
|
let currentReq = 0;
|
|
20
20
|
return {
|
|
21
|
-
async provideAutoInsertionEdit(document,
|
|
21
|
+
async provideAutoInsertionEdit(document, selection, change) {
|
|
22
|
+
// selection must at end of change
|
|
23
|
+
if (document.offsetAt(selection) !== change.rangeOffset + change.text.length) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
22
26
|
if (!isTsDocument(document)) {
|
|
23
27
|
return;
|
|
24
28
|
}
|
|
25
|
-
if (!isCharacterTyping(document,
|
|
29
|
+
if (!isCharacterTyping(document, change)) {
|
|
26
30
|
return;
|
|
27
31
|
}
|
|
28
32
|
const req = ++currentReq;
|
|
@@ -35,22 +39,24 @@ function create(ts, getTsPluginClient) {
|
|
|
35
39
|
if (!enabled) {
|
|
36
40
|
return;
|
|
37
41
|
}
|
|
38
|
-
const
|
|
39
|
-
|
|
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) {
|
|
40
46
|
return;
|
|
41
47
|
}
|
|
42
48
|
let ast;
|
|
43
|
-
let sourceCodeOffset = document.offsetAt(
|
|
44
|
-
const fileName = context.env.typescript.uriToFileName(
|
|
45
|
-
if (
|
|
46
|
-
const
|
|
47
|
-
if (
|
|
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) {
|
|
48
54
|
return;
|
|
49
55
|
}
|
|
50
|
-
ast = getAst(ts, fileName,
|
|
56
|
+
ast = getAst(ts, fileName, virtualCode.snapshot, serviceScript.scriptKind);
|
|
51
57
|
let mapped = false;
|
|
52
|
-
for (const [_1, [_2, map]] of context.language.
|
|
53
|
-
const sourceOffset = map.getSourceOffset(document.offsetAt(
|
|
58
|
+
for (const [_1, [_2, map]] of context.language.maps.forEach(virtualCode)) {
|
|
59
|
+
const sourceOffset = map.getSourceOffset(document.offsetAt(selection));
|
|
54
60
|
if (sourceOffset !== undefined) {
|
|
55
61
|
sourceCodeOffset = sourceOffset[0];
|
|
56
62
|
mapped = true;
|
|
@@ -62,9 +68,9 @@ function create(ts, getTsPluginClient) {
|
|
|
62
68
|
}
|
|
63
69
|
}
|
|
64
70
|
else {
|
|
65
|
-
ast = getAst(ts, fileName,
|
|
71
|
+
ast = getAst(ts, fileName, sourceScript.snapshot);
|
|
66
72
|
}
|
|
67
|
-
if (isBlacklistNode(ts, ast, document.offsetAt(
|
|
73
|
+
if (isBlacklistNode(ts, ast, document.offsetAt(selection), false)) {
|
|
68
74
|
return;
|
|
69
75
|
}
|
|
70
76
|
const props = await tsPluginClient?.getPropertiesAtLocation(fileName, sourceCodeOffset) ?? [];
|
|
@@ -87,21 +93,13 @@ function isTsDocument(document) {
|
|
|
87
93
|
document.languageId === 'typescriptreact';
|
|
88
94
|
}
|
|
89
95
|
const charReg = /\w/;
|
|
90
|
-
function isCharacterTyping(document,
|
|
91
|
-
const lastCharacter =
|
|
92
|
-
const
|
|
93
|
-
const position = {
|
|
94
|
-
line: rangeStart.line,
|
|
95
|
-
character: rangeStart.character + lastChange.text.length,
|
|
96
|
-
};
|
|
97
|
-
const nextCharacter = document.getText({
|
|
98
|
-
start: position,
|
|
99
|
-
end: { line: position.line, character: position.character + 1 },
|
|
100
|
-
});
|
|
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);
|
|
101
99
|
if (lastCharacter === undefined) { // delete text
|
|
102
100
|
return false;
|
|
103
101
|
}
|
|
104
|
-
if (
|
|
102
|
+
if (change.text.indexOf('\n') >= 0) { // multi-line change
|
|
105
103
|
return false;
|
|
106
104
|
}
|
|
107
105
|
return charReg.test(lastCharacter) && !charReg.test(nextCharacter);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function create(ts: typeof import('typescript')):
|
|
1
|
+
import type { LanguageServicePlugin } from '@volar/language-service';
|
|
2
|
+
export declare function create(ts: typeof import('typescript')): LanguageServicePlugin;
|
|
@@ -7,19 +7,25 @@ function create(ts) {
|
|
|
7
7
|
name: 'vue-autoinsert-parentheses',
|
|
8
8
|
create(context) {
|
|
9
9
|
return {
|
|
10
|
-
async provideAutoInsertionEdit(document,
|
|
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
16
|
if (!enabled) {
|
|
13
17
|
return;
|
|
14
18
|
}
|
|
15
|
-
if (!(0, vue_autoinsert_dotvalue_1.isCharacterTyping)(document,
|
|
19
|
+
if (!(0, vue_autoinsert_dotvalue_1.isCharacterTyping)(document, change)) {
|
|
16
20
|
return;
|
|
17
21
|
}
|
|
18
|
-
const
|
|
19
|
-
|
|
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_')) {
|
|
20
26
|
return;
|
|
21
27
|
}
|
|
22
|
-
const offset = document.offsetAt(
|
|
28
|
+
const offset = document.offsetAt(selection);
|
|
23
29
|
for (const mappedRange of virtualCode.mappings) {
|
|
24
30
|
const generatedCodeEnd = mappedRange.generatedOffsets[mappedRange.generatedOffsets.length - 1]
|
|
25
31
|
+ mappedRange.lengths[mappedRange.lengths.length - 1];
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function create():
|
|
1
|
+
import type { LanguageServicePlugin } from '@volar/language-service';
|
|
2
|
+
export declare function create(): LanguageServicePlugin;
|
|
@@ -6,24 +6,16 @@ function create() {
|
|
|
6
6
|
name: 'vue-autoinsert-space',
|
|
7
7
|
create(context) {
|
|
8
8
|
return {
|
|
9
|
-
async provideAutoInsertionEdit(document,
|
|
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
12
|
if (!enabled) {
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
15
|
-
if (
|
|
16
|
-
&& document.getText({
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}) === '{{}}') {
|
|
20
|
-
return {
|
|
21
|
-
newText: ` $0 `,
|
|
22
|
-
range: {
|
|
23
|
-
start: { line: lastChange.range.start.line, character: lastChange.range.start.character + 1 },
|
|
24
|
-
end: { line: lastChange.range.start.line, character: lastChange.range.start.character + 1 }
|
|
25
|
-
},
|
|
26
|
-
};
|
|
15
|
+
if (change.text === '{}'
|
|
16
|
+
&& document.getText().substring(change.rangeOffset - 1, change.rangeOffset + 3) === '{{}}'
|
|
17
|
+
&& document.offsetAt(selection) === change.rangeOffset + 1) {
|
|
18
|
+
return ` $0 `;
|
|
27
19
|
}
|
|
28
20
|
}
|
|
29
21
|
},
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function create():
|
|
1
|
+
import type { LanguageServicePlugin } from '@volar/language-service';
|
|
2
|
+
export declare function create(): LanguageServicePlugin;
|
|
@@ -27,11 +27,13 @@ function create() {
|
|
|
27
27
|
},
|
|
28
28
|
};
|
|
29
29
|
function worker(uri, callback) {
|
|
30
|
-
const
|
|
31
|
-
|
|
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) {
|
|
32
34
|
return;
|
|
33
35
|
}
|
|
34
|
-
return callback(virtualCode,
|
|
36
|
+
return callback(virtualCode, sourceScript);
|
|
35
37
|
}
|
|
36
38
|
},
|
|
37
39
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function create():
|
|
1
|
+
import type { LanguageServicePlugin } from '@volar/language-service';
|
|
2
|
+
export declare function create(): LanguageServicePlugin;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function create(ts: typeof import('typescript')):
|
|
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;
|
|
@@ -6,19 +6,23 @@ const shared_1 = require("@vue/shared");
|
|
|
6
6
|
const path = require("path-browserify");
|
|
7
7
|
const vue_extract_file_1 = require("../plugins/vue-extract-file");
|
|
8
8
|
const types_1 = require("../types");
|
|
9
|
-
|
|
9
|
+
const getUserPreferences_1 = require("volar-service-typescript/lib/configs/getUserPreferences");
|
|
10
|
+
function create(ts, getTsPluginClient) {
|
|
10
11
|
return {
|
|
11
12
|
name: 'vue-document-drop',
|
|
12
13
|
create(context) {
|
|
13
14
|
let casing = types_1.TagNameCasing.Pascal; // TODO
|
|
15
|
+
const tsPluginClient = getTsPluginClient?.(context);
|
|
14
16
|
return {
|
|
15
17
|
async provideDocumentDropEdits(document, _position, dataTransfer) {
|
|
16
18
|
if (document.languageId !== 'html') {
|
|
17
19
|
return;
|
|
18
20
|
}
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
|
|
21
|
+
const decoded = context.decodeEmbeddedDocumentUri(document.uri);
|
|
22
|
+
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
|
|
23
|
+
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
|
|
24
|
+
const vueVirtualCode = sourceScript?.generated?.root;
|
|
25
|
+
if (!sourceScript || !virtualCode || !(vueVirtualCode instanceof language_core_1.VueGeneratedCode)) {
|
|
22
26
|
return;
|
|
23
27
|
}
|
|
24
28
|
let importUri;
|
|
@@ -41,14 +45,28 @@ function create(ts) {
|
|
|
41
45
|
const additionalEdit = {};
|
|
42
46
|
const code = [...(0, language_core_1.forEachEmbeddedCode)(vueVirtualCode)].find(code => code.id === (sfc.scriptSetup ? 'scriptSetupFormat' : 'scriptFormat'));
|
|
43
47
|
const lastImportNode = (0, vue_extract_file_1.getLastImportNode)(ts, script.ast);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
const incomingFileName = context.env.typescript.uriToFileName(importUri);
|
|
49
|
+
let importPath;
|
|
50
|
+
const serviceScript = sourceScript.generated?.languagePlugin.typescript?.getServiceScript(vueVirtualCode);
|
|
51
|
+
if (tsPluginClient && serviceScript) {
|
|
52
|
+
const tsDocumentUri = context.encodeEmbeddedDocumentUri(sourceScript.id, serviceScript.code.id);
|
|
53
|
+
const tsDocument = context.documents.get(tsDocumentUri, serviceScript.code.languageId, serviceScript.code.snapshot);
|
|
54
|
+
const preferences = await (0, getUserPreferences_1.getUserPreferences)(context, tsDocument);
|
|
55
|
+
const importPathRequest = await tsPluginClient.getImportPathForFile(vueVirtualCode.fileName, incomingFileName, preferences);
|
|
56
|
+
if (importPathRequest) {
|
|
57
|
+
importPath = importPathRequest;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (!importPath) {
|
|
61
|
+
importPath = path.relative(path.dirname(vueVirtualCode.fileName), incomingFileName)
|
|
62
|
+
|| importUri.substring(importUri.lastIndexOf('/') + 1);
|
|
63
|
+
if (!importPath.startsWith('./') && !importPath.startsWith('../')) {
|
|
64
|
+
importPath = './' + importPath;
|
|
65
|
+
}
|
|
48
66
|
}
|
|
49
67
|
additionalEdit.changes ??= {};
|
|
50
|
-
additionalEdit.changes[context.
|
|
51
|
-
additionalEdit.changes[context.
|
|
68
|
+
additionalEdit.changes[context.encodeEmbeddedDocumentUri(sourceScript.id, code.id)] = [];
|
|
69
|
+
additionalEdit.changes[context.encodeEmbeddedDocumentUri(sourceScript.id, code.id)].push({
|
|
52
70
|
range: lastImportNode ? {
|
|
53
71
|
start: script.ast.getLineAndCharacterOfPosition(lastImportNode.end),
|
|
54
72
|
end: script.ast.getLineAndCharacterOfPosition(lastImportNode.end),
|
|
@@ -62,7 +80,7 @@ function create(ts) {
|
|
|
62
80
|
if (sfc.script) {
|
|
63
81
|
const edit = (0, vue_extract_file_1.createAddComponentToOptionEdit)(ts, sfc.script.ast, newName);
|
|
64
82
|
if (edit) {
|
|
65
|
-
additionalEdit.changes[context.
|
|
83
|
+
additionalEdit.changes[context.encodeEmbeddedDocumentUri(sourceScript.id, code.id)].push({
|
|
66
84
|
range: {
|
|
67
85
|
start: document.positionAt(edit.range.start),
|
|
68
86
|
end: document.positionAt(edit.range.end),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ServiceContext,
|
|
1
|
+
import type { ServiceContext, LanguageServicePlugin } from '@volar/language-service';
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
|
-
export declare function create(ts: typeof import('typescript'), getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined):
|
|
3
|
+
export declare function create(ts: typeof import('typescript'), getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined): LanguageServicePlugin;
|
|
4
4
|
export declare function getLastImportNode(ts: typeof import('typescript'), sourceFile: ts.SourceFile): ts.Node | undefined;
|
|
5
5
|
export declare function createAddComponentToOptionEdit(ts: typeof import('typescript'), ast: ts.SourceFile, componentName: string): {
|
|
6
6
|
range: import("@vue/language-core").TextRange;
|
|
@@ -15,11 +15,13 @@ function create(ts, getTsPluginClient) {
|
|
|
15
15
|
if (startOffset === endOffset) {
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
|
-
const
|
|
19
|
-
|
|
18
|
+
const decoded = context.decodeEmbeddedDocumentUri(document.uri);
|
|
19
|
+
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
|
|
20
|
+
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
|
|
21
|
+
if (!(sourceScript?.generated?.root instanceof language_core_1.VueGeneratedCode) || virtualCode?.id !== 'template') {
|
|
20
22
|
return;
|
|
21
23
|
}
|
|
22
|
-
const { sfc } =
|
|
24
|
+
const { sfc } = sourceScript.generated.root;
|
|
23
25
|
const script = sfc.scriptSetup ?? sfc.script;
|
|
24
26
|
if (!sfc.template || !script) {
|
|
25
27
|
return;
|
|
@@ -43,13 +45,15 @@ function create(ts, getTsPluginClient) {
|
|
|
43
45
|
async resolveCodeAction(codeAction) {
|
|
44
46
|
const { uri, range, newName } = codeAction.data;
|
|
45
47
|
const [startOffset, endOffset] = range;
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
+
const decoded = context.decodeEmbeddedDocumentUri(uri);
|
|
49
|
+
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
|
|
50
|
+
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
|
|
51
|
+
if (!(sourceScript?.generated?.root instanceof language_core_1.VueGeneratedCode) || virtualCode?.id !== 'template') {
|
|
48
52
|
return codeAction;
|
|
49
53
|
}
|
|
50
|
-
const document = context.documents.get(uri,
|
|
51
|
-
const sfcDocument = context.documents.get(
|
|
52
|
-
const { sfc } =
|
|
54
|
+
const document = context.documents.get(uri, virtualCode.languageId, virtualCode.snapshot);
|
|
55
|
+
const sfcDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
|
|
56
|
+
const { sfc } = sourceScript.generated.root;
|
|
53
57
|
const script = sfc.scriptSetup ?? sfc.script;
|
|
54
58
|
if (!sfc.template || !script) {
|
|
55
59
|
return codeAction;
|
|
@@ -58,7 +62,7 @@ function create(ts, getTsPluginClient) {
|
|
|
58
62
|
if (!templateCodeRange) {
|
|
59
63
|
return codeAction;
|
|
60
64
|
}
|
|
61
|
-
const toExtract = await tsPluginClient?.collectExtractProps(
|
|
65
|
+
const toExtract = await tsPluginClient?.collectExtractProps(sourceScript.generated.root.fileName, templateCodeRange) ?? [];
|
|
62
66
|
if (!toExtract) {
|
|
63
67
|
return codeAction;
|
|
64
68
|
}
|
|
@@ -122,7 +126,7 @@ function create(ts, getTsPluginClient) {
|
|
|
122
126
|
// editing vue sfc
|
|
123
127
|
{
|
|
124
128
|
textDocument: {
|
|
125
|
-
uri:
|
|
129
|
+
uri: sourceScript.id,
|
|
126
130
|
version: null,
|
|
127
131
|
},
|
|
128
132
|
edits: sfcEdits,
|
package/lib/plugins/vue-sfc.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LanguageServicePlugin } from '@volar/language-service';
|
|
2
2
|
import * as vue from '@vue/language-core';
|
|
3
3
|
import type { TextDocument } from 'vscode-languageserver-textdocument';
|
|
4
4
|
export interface Provide {
|
|
5
5
|
'vue/vueFile': (document: TextDocument) => vue.VueGeneratedCode | undefined;
|
|
6
6
|
}
|
|
7
|
-
export declare function create():
|
|
7
|
+
export declare function create(): LanguageServicePlugin;
|
package/lib/plugins/vue-sfc.js
CHANGED
|
@@ -17,8 +17,26 @@ function create() {
|
|
|
17
17
|
sfcDataProvider ??= html.newHTMLDataProvider('vue', (0, data_1.loadLanguageBlocks)(context.env.locale ?? 'en'));
|
|
18
18
|
return [sfcDataProvider];
|
|
19
19
|
},
|
|
20
|
+
async getFormattingOptions(document, options, context) {
|
|
21
|
+
return await worker(document, async (vueCode) => {
|
|
22
|
+
const formatSettings = await context.env.getConfiguration?.('html.format') ?? {};
|
|
23
|
+
const blockTypes = ['template', 'script', 'style'];
|
|
24
|
+
for (const customBlock of vueCode.sfc.customBlocks) {
|
|
25
|
+
blockTypes.push(customBlock.type);
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
...options,
|
|
29
|
+
...formatSettings,
|
|
30
|
+
wrapAttributes: 'auto',
|
|
31
|
+
unformatted: '',
|
|
32
|
+
contentUnformatted: blockTypes.join(','),
|
|
33
|
+
endWithNewline: options.insertFinalNewline ? true
|
|
34
|
+
: options.trimFinalNewlines ? false
|
|
35
|
+
: document.getText().endsWith('\n'),
|
|
36
|
+
};
|
|
37
|
+
}) ?? {};
|
|
38
|
+
},
|
|
20
39
|
}).create(context);
|
|
21
|
-
const htmlLanguageService = htmlPlugin.provide['html/languageService']();
|
|
22
40
|
return {
|
|
23
41
|
...htmlPlugin,
|
|
24
42
|
provide: {
|
|
@@ -28,20 +46,19 @@ function create() {
|
|
|
28
46
|
});
|
|
29
47
|
},
|
|
30
48
|
},
|
|
31
|
-
async resolveEmbeddedCodeFormattingOptions(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (code.id === 'scriptFormat' || code.id === 'scriptSetupFormat') {
|
|
49
|
+
async resolveEmbeddedCodeFormattingOptions(sourceScript, virtualCode, options) {
|
|
50
|
+
if (sourceScript.generated?.root instanceof vue.VueGeneratedCode) {
|
|
51
|
+
if (virtualCode.id === 'scriptFormat' || virtualCode.id === 'scriptSetupFormat') {
|
|
35
52
|
if (await context.env.getConfiguration?.('vue.format.script.initialIndent') ?? false) {
|
|
36
53
|
options.initialIndentLevel++;
|
|
37
54
|
}
|
|
38
55
|
}
|
|
39
|
-
else if (
|
|
56
|
+
else if (virtualCode.id.startsWith('style_')) {
|
|
40
57
|
if (await context.env.getConfiguration?.('vue.format.style.initialIndent') ?? false) {
|
|
41
58
|
options.initialIndentLevel++;
|
|
42
59
|
}
|
|
43
60
|
}
|
|
44
|
-
else if (
|
|
61
|
+
else if (virtualCode.id === 'template') {
|
|
45
62
|
if (await context.env.getConfiguration?.('vue.format.template.initialIndent') ?? true) {
|
|
46
63
|
options.initialIndentLevel++;
|
|
47
64
|
}
|
|
@@ -134,29 +151,13 @@ function create() {
|
|
|
134
151
|
return result;
|
|
135
152
|
});
|
|
136
153
|
},
|
|
137
|
-
provideDocumentFormattingEdits(document, range, options) {
|
|
138
|
-
return worker(document, async (vueCode) => {
|
|
139
|
-
const formatSettings = await context.env.getConfiguration?.('html.format') ?? {};
|
|
140
|
-
const blockTypes = ['template', 'script', 'style'];
|
|
141
|
-
for (const customBlock of vueCode.sfc.customBlocks) {
|
|
142
|
-
blockTypes.push(customBlock.type);
|
|
143
|
-
}
|
|
144
|
-
return htmlLanguageService.format(document, range, {
|
|
145
|
-
...options,
|
|
146
|
-
...formatSettings,
|
|
147
|
-
unformatted: '',
|
|
148
|
-
contentUnformatted: blockTypes.join(','),
|
|
149
|
-
endWithNewline: options.insertFinalNewline ? true
|
|
150
|
-
: options.trimFinalNewlines ? false
|
|
151
|
-
: document.getText().endsWith('\n'),
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
},
|
|
155
154
|
};
|
|
156
155
|
function worker(document, callback) {
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
156
|
+
const decoded = context.decodeEmbeddedDocumentUri(document.uri);
|
|
157
|
+
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
|
|
158
|
+
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
|
|
159
|
+
if (virtualCode instanceof vue.VueGeneratedCode) {
|
|
160
|
+
return callback(virtualCode);
|
|
160
161
|
}
|
|
161
162
|
}
|
|
162
163
|
},
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { ServiceContext, ServiceEnvironment } from '@volar/language-service';
|
|
2
|
-
import {
|
|
3
|
-
export declare function create(mode: 'html' | 'pug', ts: typeof import('typescript'), getVueOptions: (env: ServiceEnvironment) => VueCompilerOptions, getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined):
|
|
2
|
+
import { LanguageServicePlugin, VueCompilerOptions } from '../types';
|
|
3
|
+
export declare function create(mode: 'html' | 'pug', ts: typeof import('typescript'), getVueOptions: (env: ServiceEnvironment) => VueCompilerOptions, getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined): LanguageServicePlugin;
|
|
@@ -89,9 +89,10 @@ function create(mode, ts, getVueOptions, getTsPluginClient) {
|
|
|
89
89
|
}
|
|
90
90
|
let sync;
|
|
91
91
|
let currentVersion;
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
const decoded = context.decodeEmbeddedDocumentUri(document.uri);
|
|
93
|
+
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
|
|
94
|
+
if (sourceScript?.generated?.root instanceof language_core_1.VueGeneratedCode) {
|
|
95
|
+
sync = (await provideHtmlData(sourceScript.id, sourceScript.generated.root)).sync;
|
|
95
96
|
currentVersion = await sync();
|
|
96
97
|
}
|
|
97
98
|
let htmlComplete = await baseServiceInstance.provideCompletionItems?.(document, position, completionContext, token);
|
|
@@ -101,8 +102,8 @@ function create(mode, ts, getVueOptions, getTsPluginClient) {
|
|
|
101
102
|
if (!htmlComplete) {
|
|
102
103
|
return;
|
|
103
104
|
}
|
|
104
|
-
if (
|
|
105
|
-
await afterHtmlCompletion(htmlComplete, context.documents.get(
|
|
105
|
+
if (sourceScript?.generated?.root instanceof language_core_1.VueGeneratedCode) {
|
|
106
|
+
await afterHtmlCompletion(htmlComplete, context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot), sourceScript.generated.root);
|
|
106
107
|
}
|
|
107
108
|
return htmlComplete;
|
|
108
109
|
},
|
|
@@ -115,12 +116,14 @@ function create(mode, ts, getVueOptions, getTsPluginClient) {
|
|
|
115
116
|
return;
|
|
116
117
|
}
|
|
117
118
|
const result = [];
|
|
118
|
-
const
|
|
119
|
+
const decoded = context.decodeEmbeddedDocumentUri(document.uri);
|
|
120
|
+
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
|
|
121
|
+
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
|
|
119
122
|
if (!virtualCode) {
|
|
120
123
|
return;
|
|
121
124
|
}
|
|
122
125
|
for (const map of context.documents.getMaps(virtualCode)) {
|
|
123
|
-
const code = context.language.
|
|
126
|
+
const code = context.language.scripts.get(map.sourceDocument.uri)?.generated?.root;
|
|
124
127
|
const scanner = getScanner(baseServiceInstance, document);
|
|
125
128
|
if (code instanceof language_core_1.VueGeneratedCode && scanner) {
|
|
126
129
|
// visualize missing required props
|
|
@@ -213,7 +216,7 @@ function create(mode, ts, getVueOptions, getTsPluginClient) {
|
|
|
213
216
|
if (!isSupportedDocument(document)) {
|
|
214
217
|
return;
|
|
215
218
|
}
|
|
216
|
-
if (context.
|
|
219
|
+
if (context.decodeEmbeddedDocumentUri(document.uri)) {
|
|
217
220
|
updateExtraCustomData([]);
|
|
218
221
|
}
|
|
219
222
|
return baseServiceInstance.provideHover?.(document, position, token);
|
|
@@ -223,12 +226,14 @@ function create(mode, ts, getVueOptions, getTsPluginClient) {
|
|
|
223
226
|
return;
|
|
224
227
|
}
|
|
225
228
|
const originalResult = await baseServiceInstance.provideDiagnostics?.(document, token);
|
|
226
|
-
const
|
|
229
|
+
const decoded = context.decodeEmbeddedDocumentUri(document.uri);
|
|
230
|
+
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
|
|
231
|
+
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
|
|
227
232
|
if (!virtualCode) {
|
|
228
233
|
return;
|
|
229
234
|
}
|
|
230
235
|
for (const map of context.documents.getMaps(virtualCode)) {
|
|
231
|
-
const code = context.language.
|
|
236
|
+
const code = context.language.scripts.get(map.sourceDocument.uri)?.generated?.root;
|
|
232
237
|
if (!(code instanceof language_core_1.VueGeneratedCode)) {
|
|
233
238
|
continue;
|
|
234
239
|
}
|
|
@@ -269,19 +274,24 @@ function create(mode, ts, getVueOptions, getTsPluginClient) {
|
|
|
269
274
|
if (!isSupportedDocument(document)) {
|
|
270
275
|
return;
|
|
271
276
|
}
|
|
272
|
-
const
|
|
273
|
-
if (!
|
|
274
|
-
|
|
275
|
-
|
|
277
|
+
const languageService = context.inject('typescript/languageService');
|
|
278
|
+
if (!languageService) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
const decoded = context.decodeEmbeddedDocumentUri(document.uri);
|
|
282
|
+
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
|
|
283
|
+
if (!sourceScript
|
|
284
|
+
|| !(sourceScript.generated?.root instanceof language_core_1.VueGeneratedCode)
|
|
285
|
+
|| !sourceScript.generated.root.sfc.template) {
|
|
276
286
|
return [];
|
|
277
287
|
}
|
|
278
|
-
const { template } =
|
|
288
|
+
const { template } = sourceScript.generated.root.sfc;
|
|
279
289
|
const spans = common_1.getComponentSpans.call({
|
|
280
|
-
files: context.language.
|
|
281
|
-
languageService
|
|
290
|
+
files: context.language.scripts,
|
|
291
|
+
languageService,
|
|
282
292
|
typescript: ts,
|
|
283
293
|
vueOptions: getVueOptions(context.env),
|
|
284
|
-
},
|
|
294
|
+
}, sourceScript.generated.root, template, {
|
|
285
295
|
start: document.offsetAt(range.start),
|
|
286
296
|
length: document.offsetAt(range.end) - document.offsetAt(range.start),
|
|
287
297
|
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function create(ts: typeof import('typescript')):
|
|
1
|
+
import type { LanguageServicePlugin } from '@volar/language-service';
|
|
2
|
+
export declare function create(ts: typeof import('typescript')): LanguageServicePlugin;
|
|
@@ -10,7 +10,9 @@ function create(ts) {
|
|
|
10
10
|
provideCodeActions(document, range, _context) {
|
|
11
11
|
const startOffset = document.offsetAt(range.start);
|
|
12
12
|
const endOffset = document.offsetAt(range.end);
|
|
13
|
-
const
|
|
13
|
+
const decoded = context.decodeEmbeddedDocumentUri(document.uri);
|
|
14
|
+
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
|
|
15
|
+
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
|
|
14
16
|
if (!(virtualCode instanceof language_core_1.VueGeneratedCode)) {
|
|
15
17
|
return;
|
|
16
18
|
}
|
|
@@ -20,7 +22,7 @@ function create(ts) {
|
|
|
20
22
|
}
|
|
21
23
|
const templateStartOffset = template.startTagEnd;
|
|
22
24
|
const result = [];
|
|
23
|
-
for (const node of (0, language_core_1.
|
|
25
|
+
for (const node of (0, language_core_1.forEachElementNode)(template.ast)) {
|
|
24
26
|
if (startOffset > templateStartOffset + node.loc.end.offset || endOffset < templateStartOffset + node.loc.start.offset) {
|
|
25
27
|
return;
|
|
26
28
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { ServiceContext,
|
|
2
|
-
export declare function create(ts: typeof import('typescript'), getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined):
|
|
1
|
+
import type { ServiceContext, LanguageServicePlugin } from '@volar/language-service';
|
|
2
|
+
export declare function create(ts: typeof import('typescript'), getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined): LanguageServicePlugin;
|
|
@@ -10,8 +10,10 @@ function create(ts, getTsPluginClient) {
|
|
|
10
10
|
const tsPluginClient = getTsPluginClient?.(context);
|
|
11
11
|
return {
|
|
12
12
|
async provideInlayHints(document, range) {
|
|
13
|
-
const
|
|
14
|
-
|
|
13
|
+
const decoded = context.decodeEmbeddedDocumentUri(document.uri);
|
|
14
|
+
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
|
|
15
|
+
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
|
|
16
|
+
if (!(sourceScript?.generated?.root instanceof vue.VueGeneratedCode) || virtualCode?.id !== 'template') {
|
|
15
17
|
return;
|
|
16
18
|
}
|
|
17
19
|
const hoverOffsets = [];
|
|
@@ -25,9 +27,9 @@ function create(ts, getTsPluginClient) {
|
|
|
25
27
|
})]);
|
|
26
28
|
}
|
|
27
29
|
for (const [pointerPosition, hoverOffset] of hoverOffsets) {
|
|
28
|
-
for (const [_1, [_2, map]] of context.language.
|
|
30
|
+
for (const [_1, [_2, map]] of context.language.maps.forEach(virtualCode)) {
|
|
29
31
|
for (const [sourceOffset] of map.getSourceOffsets(hoverOffset)) {
|
|
30
|
-
const quickInfo = await tsPluginClient?.getQuickInfoAtPosition(
|
|
32
|
+
const quickInfo = await tsPluginClient?.getQuickInfoAtPosition(sourceScript.generated.root.fileName, sourceOffset);
|
|
31
33
|
if (quickInfo) {
|
|
32
34
|
inlayHints.push({
|
|
33
35
|
position: { line: pointerPosition.line, character: pointerPosition.character + 2 },
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function create():
|
|
1
|
+
import type { LanguageServicePlugin } from '../types';
|
|
2
|
+
export declare function create(): LanguageServicePlugin;
|
|
@@ -9,11 +9,13 @@ function create() {
|
|
|
9
9
|
async provideInlayHints(document, range) {
|
|
10
10
|
const settings = {};
|
|
11
11
|
const result = [];
|
|
12
|
-
const
|
|
13
|
-
|
|
12
|
+
const decoded = context.decodeEmbeddedDocumentUri(document.uri);
|
|
13
|
+
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
|
|
14
|
+
const vitualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
|
|
15
|
+
if (vitualCode) {
|
|
14
16
|
const start = document.offsetAt(range.start);
|
|
15
17
|
const end = document.offsetAt(range.end);
|
|
16
|
-
for (const mapping of
|
|
18
|
+
for (const mapping of vitualCode.mappings) {
|
|
17
19
|
const hint = mapping.data.__hint;
|
|
18
20
|
if (mapping.generatedOffsets[0] >= start
|
|
19
21
|
&& mapping.generatedOffsets[mapping.generatedOffsets.length - 1] + mapping.lengths[mapping.lengths.length - 1] <= end
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vue/language-service",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"data",
|
|
@@ -16,23 +16,23 @@
|
|
|
16
16
|
"update-html-data": "node ./scripts/update-html-data.js"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@volar/language-core": "~2.
|
|
20
|
-
"@volar/language-service": "~2.
|
|
21
|
-
"@volar/typescript": "~2.
|
|
19
|
+
"@volar/language-core": "~2.2.0-alpha.5",
|
|
20
|
+
"@volar/language-service": "~2.2.0-alpha.5",
|
|
21
|
+
"@volar/typescript": "~2.2.0-alpha.5",
|
|
22
22
|
"@vue/compiler-dom": "^3.4.0",
|
|
23
|
-
"@vue/language-core": "2.0.
|
|
23
|
+
"@vue/language-core": "2.0.10",
|
|
24
24
|
"@vue/shared": "^3.4.0",
|
|
25
|
-
"@vue/typescript-plugin": "2.0.
|
|
25
|
+
"@vue/typescript-plugin": "2.0.10",
|
|
26
26
|
"computeds": "^0.0.1",
|
|
27
27
|
"path-browserify": "^1.0.1",
|
|
28
|
-
"volar-service-css": "0.0.
|
|
29
|
-
"volar-service-emmet": "0.0.
|
|
30
|
-
"volar-service-html": "0.0.
|
|
31
|
-
"volar-service-json": "0.0.
|
|
32
|
-
"volar-service-pug": "0.0.
|
|
33
|
-
"volar-service-pug-beautify": "0.0.
|
|
34
|
-
"volar-service-typescript": "0.0.
|
|
35
|
-
"volar-service-typescript-twoslash-queries": "0.0.
|
|
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
36
|
"vscode-html-languageservice": "^5.1.0",
|
|
37
37
|
"vscode-languageserver-textdocument": "^1.0.11",
|
|
38
38
|
"vscode-uri": "^3.0.8"
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "latest",
|
|
42
42
|
"@types/path-browserify": "latest",
|
|
43
|
-
"@volar/kit": "~2.
|
|
43
|
+
"@volar/kit": "~2.2.0-alpha.5",
|
|
44
44
|
"vscode-languageserver-protocol": "^3.17.5"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "a20a2ee950b63a949660b7e8faf0faed0e5bad33"
|
|
47
47
|
}
|