@vue/language-service 2.0.6 → 2.0.7
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/index.d.ts +3 -2
- package/index.js +80 -23
- package/lib/ideFeatures/nameCasing.d.ts +2 -2
- package/lib/ideFeatures/nameCasing.js +17 -10
- package/lib/plugins/data.js +6 -3
- package/lib/plugins/vue-autoinsert-dotvalue.d.ts +2 -2
- package/lib/plugins/vue-autoinsert-dotvalue.js +16 -8
- package/lib/plugins/vue-autoinsert-parentheses.js +6 -3
- package/lib/plugins/vue-autoinsert-space.js +2 -1
- package/lib/plugins/vue-codelens-references.js +4 -2
- package/lib/plugins/vue-directive-comments.js +4 -3
- package/lib/plugins/vue-document-drop.js +8 -4
- package/lib/plugins/vue-extract-file.d.ts +2 -2
- package/lib/plugins/vue-extract-file.js +20 -10
- package/lib/plugins/vue-sfc.js +11 -7
- package/lib/plugins/vue-template.d.ts +2 -2
- package/lib/plugins/vue-template.js +67 -23
- package/lib/plugins/vue-toggle-v-bind-codeaction.js +2 -1
- package/lib/plugins/vue-twoslash-queries.d.ts +2 -2
- package/lib/plugins/vue-twoslash-queries.js +4 -2
- package/lib/plugins/vue-visualize-hidden-callback-param.js +2 -1
- package/package.json +19 -19
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, ServicePlugin } 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,
|
|
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): ServicePlugin[];
|
|
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,83 @@ 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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
(0,
|
|
49
|
-
(0
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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 getPropertiesAtLocation_1 = require("@vue/typescript-plugin/lib/requests/getPropertiesAtLocation");
|
|
46
|
+
const getQuickInfoAtPosition_1 = require("@vue/typescript-plugin/lib/requests/getQuickInfoAtPosition");
|
|
47
|
+
function createVueServicePlugins(ts, getVueOptions, getTsPluginClient = createDefaultGetTsPluginClient(ts, getVueOptions), hybridMode = false) {
|
|
48
|
+
const plugins = [];
|
|
49
|
+
if (!hybridMode) {
|
|
50
|
+
plugins.push(...(0, volar_service_typescript_1.create)(ts));
|
|
51
|
+
for (let i = 0; i < plugins.length; i++) {
|
|
52
|
+
const plugin = plugins[i];
|
|
53
|
+
if (plugin.name === 'typescript-semantic') {
|
|
54
|
+
plugins[i] = {
|
|
55
|
+
...plugin,
|
|
56
|
+
create(context) {
|
|
57
|
+
const created = plugin.create(context);
|
|
58
|
+
if (!context.language.typescript) {
|
|
59
|
+
return created;
|
|
60
|
+
}
|
|
61
|
+
const languageService = created.provide['typescript/languageService']();
|
|
62
|
+
const vueOptions = getVueOptions(context.env);
|
|
63
|
+
(0, common_1.decorateLanguageServiceForVue)(context.language.files, languageService, vueOptions, ts, false);
|
|
64
|
+
return created;
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
plugins.push((0, syntactic_1.create)(ts), (0, docCommentTemplate_1.create)(ts));
|
|
73
|
+
}
|
|
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
|
+
return plugins;
|
|
62
76
|
}
|
|
63
77
|
exports.createVueServicePlugins = createVueServicePlugins;
|
|
78
|
+
function createDefaultGetTsPluginClient(ts, getVueOptions) {
|
|
79
|
+
return context => {
|
|
80
|
+
if (!context.language.typescript) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const requestContext = {
|
|
84
|
+
typescript: ts,
|
|
85
|
+
files: context.language.files,
|
|
86
|
+
languageService: context.inject('typescript/languageService'),
|
|
87
|
+
vueOptions: getVueOptions(context.env),
|
|
88
|
+
isTsPlugin: false,
|
|
89
|
+
getFileId: context.env.typescript.fileNameToUri,
|
|
90
|
+
};
|
|
91
|
+
return {
|
|
92
|
+
async collectExtractProps(...args) {
|
|
93
|
+
return await collectExtractProps_1.collectExtractProps.apply(requestContext, args);
|
|
94
|
+
},
|
|
95
|
+
async getPropertiesAtLocation(...args) {
|
|
96
|
+
return await getPropertiesAtLocation_1.getPropertiesAtLocation.apply(requestContext, args);
|
|
97
|
+
},
|
|
98
|
+
async getComponentEvents(...args) {
|
|
99
|
+
return await componentInfos_1.getComponentEvents.apply(requestContext, args);
|
|
100
|
+
},
|
|
101
|
+
async getComponentNames(...args) {
|
|
102
|
+
return await componentInfos_1.getComponentNames.apply(requestContext, args);
|
|
103
|
+
},
|
|
104
|
+
async getComponentProps(...args) {
|
|
105
|
+
return await componentInfos_1.getComponentProps.apply(requestContext, args);
|
|
106
|
+
},
|
|
107
|
+
async getElementAttrs(...args) {
|
|
108
|
+
return await componentInfos_1.getElementAttrs.apply(requestContext, args);
|
|
109
|
+
},
|
|
110
|
+
async getTemplateContextProps(...args) {
|
|
111
|
+
return await componentInfos_1.getTemplateContextProps.apply(requestContext, args);
|
|
112
|
+
},
|
|
113
|
+
async getQuickInfoAtPosition(...args) {
|
|
114
|
+
return await getQuickInfoAtPosition_1.getQuickInfoAtPosition.apply(requestContext, args);
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
;
|
|
119
|
+
}
|
|
120
|
+
exports.createDefaultGetTsPluginClient = createDefaultGetTsPluginClient;
|
|
64
121
|
//# 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
|
|
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;
|
|
@@ -7,18 +7,21 @@ const computeds_1 = require("computeds");
|
|
|
7
7
|
const types_1 = require("../types");
|
|
8
8
|
async function convertTagName(context, uri, casing, tsPluginClient) {
|
|
9
9
|
const sourceFile = context.language.files.get(uri);
|
|
10
|
-
if (!sourceFile)
|
|
10
|
+
if (!sourceFile) {
|
|
11
11
|
return;
|
|
12
|
+
}
|
|
12
13
|
const rootCode = sourceFile?.generated?.code;
|
|
13
|
-
if (!(rootCode instanceof language_core_1.VueGeneratedCode))
|
|
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
|
|
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);
|
|
@@ -41,23 +44,26 @@ async function convertTagName(context, uri, casing, tsPluginClient) {
|
|
|
41
44
|
exports.convertTagName = convertTagName;
|
|
42
45
|
async function convertAttrName(context, uri, casing, tsPluginClient) {
|
|
43
46
|
const sourceFile = context.language.files.get(uri);
|
|
44
|
-
if (!sourceFile)
|
|
47
|
+
if (!sourceFile) {
|
|
45
48
|
return;
|
|
49
|
+
}
|
|
46
50
|
const rootCode = sourceFile?.generated?.code;
|
|
47
|
-
if (!(rootCode instanceof language_core_1.VueGeneratedCode))
|
|
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
|
|
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
|
|
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) {
|
|
@@ -163,8 +169,9 @@ 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) {
|
package/lib/plugins/data.js
CHANGED
|
@@ -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
|
-
|
|
38
|
+
}
|
|
39
|
+
if (vSlot) {
|
|
39
40
|
data.globalAttributes?.push({ ...vSlot, name: '#' });
|
|
40
|
-
|
|
41
|
+
}
|
|
42
|
+
if (vBind) {
|
|
41
43
|
data.globalAttributes?.push({ ...vBind, name: ':' });
|
|
44
|
+
}
|
|
42
45
|
return data;
|
|
43
46
|
}
|
|
44
47
|
exports.loadTemplateData = loadTemplateData;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { ServicePlugin } from '@volar/language-service';
|
|
1
|
+
import type { ServiceContext, ServicePlugin } from '@volar/language-service';
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
3
|
import type * as vscode from 'vscode-languageserver-protocol';
|
|
4
4
|
import type { TextDocument } from 'vscode-languageserver-textdocument';
|
|
5
|
-
export declare function create(ts: typeof import('typescript'),
|
|
5
|
+
export declare function create(ts: typeof import('typescript'), getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined): ServicePlugin;
|
|
6
6
|
export declare function isCharacterTyping(document: TextDocument, lastChange: {
|
|
7
7
|
range: vscode.Range;
|
|
8
8
|
text: string;
|
|
@@ -11,28 +11,34 @@ function getAst(ts, fileName, snapshot, scriptKind) {
|
|
|
11
11
|
}
|
|
12
12
|
return ast;
|
|
13
13
|
}
|
|
14
|
-
function create(ts,
|
|
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
21
|
async provideAutoInsertionEdit(document, position, lastChange) {
|
|
21
|
-
if (!isTsDocument(document))
|
|
22
|
+
if (!isTsDocument(document)) {
|
|
22
23
|
return;
|
|
23
|
-
|
|
24
|
+
}
|
|
25
|
+
if (!isCharacterTyping(document, lastChange)) {
|
|
24
26
|
return;
|
|
27
|
+
}
|
|
25
28
|
const req = ++currentReq;
|
|
26
29
|
// Wait for tsserver to sync
|
|
27
30
|
await sleep(250);
|
|
28
|
-
if (req !== currentReq)
|
|
31
|
+
if (req !== currentReq) {
|
|
29
32
|
return;
|
|
33
|
+
}
|
|
30
34
|
const enabled = await context.env.getConfiguration?.('vue.autoInsert.dotValue') ?? true;
|
|
31
|
-
if (!enabled)
|
|
35
|
+
if (!enabled) {
|
|
32
36
|
return;
|
|
37
|
+
}
|
|
33
38
|
const [code, file] = context.documents.getVirtualCodeByUri(document.uri);
|
|
34
|
-
if (!file)
|
|
39
|
+
if (!file) {
|
|
35
40
|
return;
|
|
41
|
+
}
|
|
36
42
|
let ast;
|
|
37
43
|
let sourceCodeOffset = document.offsetAt(position);
|
|
38
44
|
const fileName = context.env.typescript.uriToFileName(file.id);
|
|
@@ -58,8 +64,9 @@ function create(ts, tsPluginClient) {
|
|
|
58
64
|
else {
|
|
59
65
|
ast = getAst(ts, fileName, file.snapshot);
|
|
60
66
|
}
|
|
61
|
-
if (isBlacklistNode(ts, ast, document.offsetAt(position), false))
|
|
67
|
+
if (isBlacklistNode(ts, ast, document.offsetAt(position), false)) {
|
|
62
68
|
return;
|
|
69
|
+
}
|
|
63
70
|
const props = await tsPluginClient?.getPropertiesAtLocation(fileName, sourceCodeOffset) ?? [];
|
|
64
71
|
if (props.some(prop => prop === 'value')) {
|
|
65
72
|
return '${1:.value}';
|
|
@@ -137,8 +144,9 @@ function isBlacklistNode(ts, node, pos, allowAccessDotValue) {
|
|
|
137
144
|
else {
|
|
138
145
|
let _isBlacklistNode = false;
|
|
139
146
|
node.forEachChild(node => {
|
|
140
|
-
if (_isBlacklistNode)
|
|
147
|
+
if (_isBlacklistNode) {
|
|
141
148
|
return;
|
|
149
|
+
}
|
|
142
150
|
if (pos >= node.getFullStart() && pos <= node.getEnd()) {
|
|
143
151
|
if (isBlacklistNode(ts, node, pos, allowAccessDotValue)) {
|
|
144
152
|
_isBlacklistNode = true;
|
|
@@ -9,13 +9,16 @@ function create(ts) {
|
|
|
9
9
|
return {
|
|
10
10
|
async provideAutoInsertionEdit(document, position, lastChange) {
|
|
11
11
|
const enabled = await context.env.getConfiguration?.('vue.autoInsert.parentheses') ?? false;
|
|
12
|
-
if (!enabled)
|
|
12
|
+
if (!enabled) {
|
|
13
13
|
return;
|
|
14
|
-
|
|
14
|
+
}
|
|
15
|
+
if (!(0, vue_autoinsert_dotvalue_1.isCharacterTyping)(document, lastChange)) {
|
|
15
16
|
return;
|
|
17
|
+
}
|
|
16
18
|
const [virtualCode] = context.documents.getVirtualCodeByUri(document.uri);
|
|
17
|
-
if (virtualCode?.id !== 'template_format')
|
|
19
|
+
if (virtualCode?.id !== 'template_format') {
|
|
18
20
|
return;
|
|
21
|
+
}
|
|
19
22
|
const offset = document.offsetAt(position);
|
|
20
23
|
for (const mappedRange of virtualCode.mappings) {
|
|
21
24
|
const generatedCodeEnd = mappedRange.generatedOffsets[mappedRange.generatedOffsets.length - 1]
|
|
@@ -9,8 +9,9 @@ function create() {
|
|
|
9
9
|
async provideAutoInsertionEdit(document, _, lastChange) {
|
|
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
|
+
}
|
|
14
15
|
if (lastChange.text === '{}'
|
|
15
16
|
&& document.getText({
|
|
16
17
|
start: { line: lastChange.range.start.line, character: lastChange.range.start.character - 1 },
|
|
@@ -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]
|
|
@@ -27,8 +28,9 @@ function create() {
|
|
|
27
28
|
};
|
|
28
29
|
function worker(uri, callback) {
|
|
29
30
|
const [virtualCode, sourceFile] = context.documents.getVirtualCodeByUri(uri);
|
|
30
|
-
if (!(sourceFile?.generated?.code instanceof language_core_1.VueGeneratedCode) || !sourceFile)
|
|
31
|
+
if (!(sourceFile?.generated?.code instanceof language_core_1.VueGeneratedCode) || !sourceFile) {
|
|
31
32
|
return;
|
|
33
|
+
}
|
|
32
34
|
return callback(virtualCode, sourceFile);
|
|
33
35
|
}
|
|
34
36
|
},
|
|
@@ -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
|
}
|
|
@@ -13,27 +13,31 @@ function create(ts) {
|
|
|
13
13
|
let casing = types_1.TagNameCasing.Pascal; // TODO
|
|
14
14
|
return {
|
|
15
15
|
async provideDocumentDropEdits(document, _position, dataTransfer) {
|
|
16
|
-
if (document.languageId !== 'html')
|
|
16
|
+
if (document.languageId !== 'html') {
|
|
17
17
|
return;
|
|
18
|
+
}
|
|
18
19
|
const [virtualCode, sourceFile] = context.documents.getVirtualCodeByUri(document.uri);
|
|
19
20
|
const vueVirtualCode = sourceFile?.generated?.code;
|
|
20
|
-
if (!virtualCode || !(vueVirtualCode instanceof language_core_1.VueGeneratedCode))
|
|
21
|
+
if (!virtualCode || !(vueVirtualCode instanceof language_core_1.VueGeneratedCode)) {
|
|
21
22
|
return;
|
|
23
|
+
}
|
|
22
24
|
let importUri;
|
|
23
25
|
for (const [mimeType, item] of dataTransfer) {
|
|
24
26
|
if (mimeType === 'text/uri-list') {
|
|
25
27
|
importUri = item.value;
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
|
-
if (!importUri?.endsWith('.vue'))
|
|
30
|
+
if (!importUri?.endsWith('.vue')) {
|
|
29
31
|
return;
|
|
32
|
+
}
|
|
30
33
|
let baseName = importUri.substring(importUri.lastIndexOf('/') + 1);
|
|
31
34
|
baseName = baseName.substring(0, baseName.lastIndexOf('.'));
|
|
32
35
|
const newName = (0, shared_1.capitalize)((0, shared_1.camelize)(baseName));
|
|
33
36
|
const { sfc } = vueVirtualCode;
|
|
34
37
|
const script = sfc.scriptSetup ?? sfc.script;
|
|
35
|
-
if (!script)
|
|
38
|
+
if (!script) {
|
|
36
39
|
return;
|
|
40
|
+
}
|
|
37
41
|
const additionalEdit = {};
|
|
38
42
|
const code = [...(0, language_core_1.forEachEmbeddedCode)(vueVirtualCode)].find(code => code.id === (sfc.scriptSetup ? 'scriptSetupFormat' : 'scriptFormat'));
|
|
39
43
|
const lastImportNode = (0, vue_extract_file_1.getLastImportNode)(ts, script.ast);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ServicePlugin } from '@volar/language-service';
|
|
1
|
+
import type { ServiceContext, ServicePlugin } from '@volar/language-service';
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
|
-
export declare function create(ts: typeof import('typescript'),
|
|
3
|
+
export declare function create(ts: typeof import('typescript'), getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined): ServicePlugin;
|
|
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;
|
|
@@ -3,10 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createAddComponentToOptionEdit = exports.getLastImportNode = exports.create = void 0;
|
|
4
4
|
const language_core_1 = require("@vue/language-core");
|
|
5
5
|
const unicodeReg = /\\u/g;
|
|
6
|
-
function create(ts,
|
|
6
|
+
function create(ts, getTsPluginClient) {
|
|
7
7
|
return {
|
|
8
8
|
name: 'vue-extract-file',
|
|
9
9
|
create(context) {
|
|
10
|
+
const tsPluginClient = getTsPluginClient?.(context);
|
|
10
11
|
return {
|
|
11
12
|
async provideCodeActions(document, range, _context) {
|
|
12
13
|
const startOffset = document.offsetAt(range.start);
|
|
@@ -15,15 +16,18 @@ function create(ts, tsPluginClient) {
|
|
|
15
16
|
return;
|
|
16
17
|
}
|
|
17
18
|
const [code, vueCode] = context.documents.getVirtualCodeByUri(document.uri);
|
|
18
|
-
if (!(vueCode?.generated?.code instanceof language_core_1.VueGeneratedCode) || code?.id !== 'template')
|
|
19
|
+
if (!(vueCode?.generated?.code instanceof language_core_1.VueGeneratedCode) || code?.id !== 'template') {
|
|
19
20
|
return;
|
|
21
|
+
}
|
|
20
22
|
const { sfc } = vueCode.generated.code;
|
|
21
23
|
const script = sfc.scriptSetup ?? sfc.script;
|
|
22
|
-
if (!sfc.template || !script)
|
|
24
|
+
if (!sfc.template || !script) {
|
|
23
25
|
return;
|
|
26
|
+
}
|
|
24
27
|
const templateCodeRange = selectTemplateCode(startOffset, endOffset, sfc.template);
|
|
25
|
-
if (!templateCodeRange)
|
|
28
|
+
if (!templateCodeRange) {
|
|
26
29
|
return;
|
|
30
|
+
}
|
|
27
31
|
return [
|
|
28
32
|
{
|
|
29
33
|
title: 'Extract into new dumb component',
|
|
@@ -40,20 +44,24 @@ function create(ts, tsPluginClient) {
|
|
|
40
44
|
const { uri, range, newName } = codeAction.data;
|
|
41
45
|
const [startOffset, endOffset] = range;
|
|
42
46
|
const [code, sourceFile] = context.documents.getVirtualCodeByUri(uri);
|
|
43
|
-
if (!(sourceFile?.generated?.code instanceof language_core_1.VueGeneratedCode) || code?.id !== 'template')
|
|
47
|
+
if (!(sourceFile?.generated?.code instanceof language_core_1.VueGeneratedCode) || code?.id !== 'template') {
|
|
44
48
|
return codeAction;
|
|
49
|
+
}
|
|
45
50
|
const document = context.documents.get(uri, code.languageId, code.snapshot);
|
|
46
51
|
const sfcDocument = context.documents.get(sourceFile.id, sourceFile.languageId, sourceFile.snapshot);
|
|
47
52
|
const { sfc } = sourceFile.generated.code;
|
|
48
53
|
const script = sfc.scriptSetup ?? sfc.script;
|
|
49
|
-
if (!sfc.template || !script)
|
|
54
|
+
if (!sfc.template || !script) {
|
|
50
55
|
return codeAction;
|
|
56
|
+
}
|
|
51
57
|
const templateCodeRange = selectTemplateCode(startOffset, endOffset, sfc.template);
|
|
52
|
-
if (!templateCodeRange)
|
|
58
|
+
if (!templateCodeRange) {
|
|
53
59
|
return codeAction;
|
|
60
|
+
}
|
|
54
61
|
const toExtract = await tsPluginClient?.collectExtractProps(sourceFile.generated.code.fileName, templateCodeRange) ?? [];
|
|
55
|
-
if (!toExtract)
|
|
62
|
+
if (!toExtract) {
|
|
56
63
|
return codeAction;
|
|
64
|
+
}
|
|
57
65
|
const templateInitialIndent = await context.env.getConfiguration('vue.format.template.initialIndent') ?? true;
|
|
58
66
|
const scriptInitialIndent = await context.env.getConfiguration('vue.format.script.initialIndent') ?? false;
|
|
59
67
|
const newUri = sfcDocument.uri.substring(0, sfcDocument.uri.lastIndexOf('/') + 1) + `${newName}.vue`;
|
|
@@ -200,8 +208,9 @@ function selectTemplateCode(startOffset, endOffset, templateBlock) {
|
|
|
200
208
|
}
|
|
201
209
|
}
|
|
202
210
|
function constructTag(name, attributes, initialIndent, content) {
|
|
203
|
-
if (initialIndent)
|
|
211
|
+
if (initialIndent) {
|
|
204
212
|
content = content.split('\n').map(line => `\t${line}`).join('\n');
|
|
213
|
+
}
|
|
205
214
|
const attributesString = attributes.length ? ` ${attributes.join(' ')}` : '';
|
|
206
215
|
return `<${name}${attributesString}>\n${content}\n</${name}>\n`;
|
|
207
216
|
}
|
|
@@ -220,8 +229,9 @@ function getLastImportNode(ts, sourceFile) {
|
|
|
220
229
|
exports.getLastImportNode = getLastImportNode;
|
|
221
230
|
function createAddComponentToOptionEdit(ts, ast, componentName) {
|
|
222
231
|
const exportDefault = language_core_1.scriptRanges.parseScriptRanges(ts, ast, false, true).exportDefault;
|
|
223
|
-
if (!exportDefault)
|
|
232
|
+
if (!exportDefault) {
|
|
224
233
|
return;
|
|
234
|
+
}
|
|
225
235
|
// https://github.com/microsoft/TypeScript/issues/36174
|
|
226
236
|
const printer = ts.createPrinter();
|
|
227
237
|
if (exportDefault.componentsOption && exportDefault.componentsOptionNode) {
|
package/lib/plugins/vue-sfc.js
CHANGED
|
@@ -12,16 +12,18 @@ function create() {
|
|
|
12
12
|
create(context) {
|
|
13
13
|
const htmlPlugin = (0, volar_service_html_1.create)({
|
|
14
14
|
documentSelector: ['vue'],
|
|
15
|
-
|
|
15
|
+
useDefaultDataProvider: false,
|
|
16
|
+
getCustomData(context) {
|
|
17
|
+
sfcDataProvider ??= html.newHTMLDataProvider('vue', (0, data_1.loadLanguageBlocks)(context.env.locale ?? 'en'));
|
|
18
|
+
return [sfcDataProvider];
|
|
19
|
+
},
|
|
16
20
|
}).create(context);
|
|
17
21
|
const htmlLanguageService = htmlPlugin.provide['html/languageService']();
|
|
18
|
-
sfcDataProvider ??= html.newHTMLDataProvider('vue', (0, data_1.loadLanguageBlocks)(context.env.locale ?? 'en'));
|
|
19
|
-
htmlLanguageService.setDataProviders(false, [sfcDataProvider]);
|
|
20
22
|
return {
|
|
21
23
|
...htmlPlugin,
|
|
22
24
|
provide: {
|
|
23
25
|
'vue/vueFile': document => {
|
|
24
|
-
return worker(document,
|
|
26
|
+
return worker(document, vueFile => {
|
|
25
27
|
return vueFile;
|
|
26
28
|
});
|
|
27
29
|
},
|
|
@@ -49,7 +51,7 @@ function create() {
|
|
|
49
51
|
},
|
|
50
52
|
provideDocumentLinks: undefined,
|
|
51
53
|
provideDocumentSymbols(document) {
|
|
52
|
-
return worker(document,
|
|
54
|
+
return worker(document, vueSourceFile => {
|
|
53
55
|
const result = [];
|
|
54
56
|
const descriptor = vueSourceFile.sfc;
|
|
55
57
|
if (descriptor.template) {
|
|
@@ -96,10 +98,12 @@ function create() {
|
|
|
96
98
|
}
|
|
97
99
|
for (const style of descriptor.styles) {
|
|
98
100
|
let name = 'style';
|
|
99
|
-
if (style.scoped)
|
|
101
|
+
if (style.scoped) {
|
|
100
102
|
name += ' scoped';
|
|
101
|
-
|
|
103
|
+
}
|
|
104
|
+
if (style.module) {
|
|
102
105
|
name += ' module';
|
|
106
|
+
}
|
|
103
107
|
result.push({
|
|
104
108
|
name,
|
|
105
109
|
kind: 2,
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { ServiceEnvironment } from '@volar/language-service';
|
|
1
|
+
import type { ServiceContext, ServiceEnvironment } from '@volar/language-service';
|
|
2
2
|
import { ServicePlugin, VueCompilerOptions } from '../types';
|
|
3
|
-
export declare function create(mode: 'html' | 'pug', ts: typeof import('typescript'), getVueOptions: (env: ServiceEnvironment) => VueCompilerOptions,
|
|
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): ServicePlugin;
|
|
@@ -10,9 +10,10 @@ const nameCasing_1 = require("../ideFeatures/nameCasing");
|
|
|
10
10
|
const types_1 = require("../types");
|
|
11
11
|
const data_1 = require("./data");
|
|
12
12
|
const vscode_uri_1 = require("vscode-uri");
|
|
13
|
+
const common_1 = require("@vue/typescript-plugin/lib/common");
|
|
13
14
|
let builtInData;
|
|
14
15
|
let modelData;
|
|
15
|
-
function create(mode, ts, getVueOptions,
|
|
16
|
+
function create(mode, ts, getVueOptions, getTsPluginClient) {
|
|
16
17
|
let customData = [];
|
|
17
18
|
let extraCustomData = [];
|
|
18
19
|
const onDidChangeCustomDataListeners = new Set();
|
|
@@ -41,6 +42,7 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
|
|
|
41
42
|
'@', // vue event shorthand
|
|
42
43
|
],
|
|
43
44
|
create(context) {
|
|
45
|
+
const tsPluginClient = getTsPluginClient?.(context);
|
|
44
46
|
const baseServiceInstance = baseService.create(context);
|
|
45
47
|
const vueCompilerOptions = getVueOptions(context.env);
|
|
46
48
|
builtInData ??= (0, data_1.loadTemplateData)(context.env.locale ?? 'en');
|
|
@@ -82,8 +84,9 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
|
|
|
82
84
|
disposable?.dispose();
|
|
83
85
|
},
|
|
84
86
|
async provideCompletionItems(document, position, completionContext, token) {
|
|
85
|
-
if (!isSupportedDocument(document))
|
|
87
|
+
if (!isSupportedDocument(document)) {
|
|
86
88
|
return;
|
|
89
|
+
}
|
|
87
90
|
let sync;
|
|
88
91
|
let currentVersion;
|
|
89
92
|
const [_, sourceFile] = context.documents.getVirtualCodeByUri(document.uri);
|
|
@@ -95,23 +98,27 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
|
|
|
95
98
|
while (currentVersion !== (currentVersion = await sync?.())) {
|
|
96
99
|
htmlComplete = await baseServiceInstance.provideCompletionItems?.(document, position, completionContext, token);
|
|
97
100
|
}
|
|
98
|
-
if (!htmlComplete)
|
|
101
|
+
if (!htmlComplete) {
|
|
99
102
|
return;
|
|
103
|
+
}
|
|
100
104
|
if (sourceFile?.generated?.code instanceof language_core_1.VueGeneratedCode) {
|
|
101
105
|
await afterHtmlCompletion(htmlComplete, context.documents.get(sourceFile.id, sourceFile.languageId, sourceFile.snapshot), sourceFile.generated.code);
|
|
102
106
|
}
|
|
103
107
|
return htmlComplete;
|
|
104
108
|
},
|
|
105
109
|
async provideInlayHints(document) {
|
|
106
|
-
if (!isSupportedDocument(document))
|
|
110
|
+
if (!isSupportedDocument(document)) {
|
|
107
111
|
return;
|
|
112
|
+
}
|
|
108
113
|
const enabled = await context.env.getConfiguration?.('vue.inlayHints.missingProps') ?? false;
|
|
109
|
-
if (!enabled)
|
|
114
|
+
if (!enabled) {
|
|
110
115
|
return;
|
|
116
|
+
}
|
|
111
117
|
const result = [];
|
|
112
118
|
const [virtualCode] = context.documents.getVirtualCodeByUri(document.uri);
|
|
113
|
-
if (!virtualCode)
|
|
119
|
+
if (!virtualCode) {
|
|
114
120
|
return;
|
|
121
|
+
}
|
|
115
122
|
for (const map of context.documents.getMaps(virtualCode)) {
|
|
116
123
|
const code = context.language.files.get(map.sourceDocument.uri)?.generated?.code;
|
|
117
124
|
const scanner = getScanner(baseServiceInstance, document);
|
|
@@ -203,23 +210,28 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
|
|
|
203
210
|
return result;
|
|
204
211
|
},
|
|
205
212
|
provideHover(document, position, token) {
|
|
206
|
-
if (!isSupportedDocument(document))
|
|
213
|
+
if (!isSupportedDocument(document)) {
|
|
207
214
|
return;
|
|
208
|
-
|
|
215
|
+
}
|
|
216
|
+
if (context.documents.getVirtualCodeByUri(document.uri)[0]) {
|
|
209
217
|
updateExtraCustomData([]);
|
|
218
|
+
}
|
|
210
219
|
return baseServiceInstance.provideHover?.(document, position, token);
|
|
211
220
|
},
|
|
212
221
|
async provideDiagnostics(document, token) {
|
|
213
|
-
if (!isSupportedDocument(document))
|
|
222
|
+
if (!isSupportedDocument(document)) {
|
|
214
223
|
return;
|
|
224
|
+
}
|
|
215
225
|
const originalResult = await baseServiceInstance.provideDiagnostics?.(document, token);
|
|
216
226
|
const [virtualCode] = context.documents.getVirtualCodeByUri(document.uri);
|
|
217
|
-
if (!virtualCode)
|
|
227
|
+
if (!virtualCode) {
|
|
218
228
|
return;
|
|
229
|
+
}
|
|
219
230
|
for (const map of context.documents.getMaps(virtualCode)) {
|
|
220
231
|
const code = context.language.files.get(map.sourceDocument.uri)?.generated?.code;
|
|
221
|
-
if (!(code instanceof language_core_1.VueGeneratedCode))
|
|
232
|
+
if (!(code instanceof language_core_1.VueGeneratedCode)) {
|
|
222
233
|
continue;
|
|
234
|
+
}
|
|
223
235
|
const templateErrors = [];
|
|
224
236
|
const { template } = code.sfc;
|
|
225
237
|
if (template) {
|
|
@@ -253,18 +265,53 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
|
|
|
253
265
|
];
|
|
254
266
|
}
|
|
255
267
|
},
|
|
268
|
+
provideDocumentSemanticTokens(document, range, legend) {
|
|
269
|
+
if (!isSupportedDocument(document)) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
const [_virtualCode, sourceFile] = context.documents.getVirtualCodeByUri(document.uri);
|
|
273
|
+
if (!sourceFile
|
|
274
|
+
|| !(sourceFile.generated?.code instanceof language_core_1.VueGeneratedCode)
|
|
275
|
+
|| !sourceFile.generated.code.sfc.template) {
|
|
276
|
+
return [];
|
|
277
|
+
}
|
|
278
|
+
const { template } = sourceFile.generated.code.sfc;
|
|
279
|
+
const spans = common_1.getComponentSpans.call({
|
|
280
|
+
files: context.language.files,
|
|
281
|
+
languageService: context.inject('typescript/languageService'),
|
|
282
|
+
typescript: ts,
|
|
283
|
+
vueOptions: getVueOptions(context.env),
|
|
284
|
+
}, sourceFile.generated.code, template, {
|
|
285
|
+
start: document.offsetAt(range.start),
|
|
286
|
+
length: document.offsetAt(range.end) - document.offsetAt(range.start),
|
|
287
|
+
});
|
|
288
|
+
const classTokenIndex = legend.tokenTypes.indexOf('class');
|
|
289
|
+
return spans.map(span => {
|
|
290
|
+
const start = document.positionAt(span.start);
|
|
291
|
+
return [
|
|
292
|
+
start.line,
|
|
293
|
+
start.character,
|
|
294
|
+
span.length,
|
|
295
|
+
classTokenIndex,
|
|
296
|
+
0,
|
|
297
|
+
];
|
|
298
|
+
});
|
|
299
|
+
},
|
|
256
300
|
};
|
|
257
301
|
async function provideHtmlData(sourceDocumentUri, vueCode) {
|
|
258
302
|
await (initializing ??= initialize());
|
|
259
303
|
const casing = await (0, nameCasing_1.getNameCasing)(context, sourceDocumentUri, tsPluginClient);
|
|
260
304
|
if (builtInData.tags) {
|
|
261
305
|
for (const tag of builtInData.tags) {
|
|
262
|
-
if (tag.name === 'slot')
|
|
306
|
+
if (tag.name === 'slot') {
|
|
263
307
|
continue;
|
|
264
|
-
|
|
308
|
+
}
|
|
309
|
+
if (tag.name === 'component') {
|
|
265
310
|
continue;
|
|
266
|
-
|
|
311
|
+
}
|
|
312
|
+
if (tag.name === 'template') {
|
|
267
313
|
continue;
|
|
314
|
+
}
|
|
268
315
|
if (casing.tag === types_1.TagNameCasing.Kebab) {
|
|
269
316
|
tag.name = (0, language_core_1.hyphenateTag)(tag.name);
|
|
270
317
|
}
|
|
@@ -324,10 +371,8 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
|
|
|
324
371
|
}
|
|
325
372
|
return tags;
|
|
326
373
|
},
|
|
327
|
-
provideAttributes:
|
|
328
|
-
|
|
329
|
-
let failed = false;
|
|
330
|
-
let tagInfo = tagInfos.get(tag);
|
|
374
|
+
provideAttributes: tag => {
|
|
375
|
+
const tagInfo = tagInfos.get(tag);
|
|
331
376
|
if (!tagInfo) {
|
|
332
377
|
promises.push((async () => {
|
|
333
378
|
const attrs = await tsPluginClient?.getElementAttrs(vueCode.fileName, tag) ?? [];
|
|
@@ -342,9 +387,6 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
|
|
|
342
387
|
})());
|
|
343
388
|
return [];
|
|
344
389
|
}
|
|
345
|
-
if (failed) {
|
|
346
|
-
return [];
|
|
347
|
-
}
|
|
348
390
|
const { attrs, props, events } = tagInfo;
|
|
349
391
|
const attributes = [];
|
|
350
392
|
const _tsCodegen = language_core_1.tsCodegen.get(vueCode.sfc);
|
|
@@ -467,8 +509,9 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
|
|
|
467
509
|
const textWithoutModifier = replacement.text.split('.')[0];
|
|
468
510
|
if (validModifiers && hasModifier) {
|
|
469
511
|
for (const modifier in validModifiers) {
|
|
470
|
-
if (modifiers.includes(modifier))
|
|
512
|
+
if (modifiers.includes(modifier)) {
|
|
471
513
|
continue;
|
|
514
|
+
}
|
|
472
515
|
const modifierDes = validModifiers[modifier];
|
|
473
516
|
const insertText = textWithoutModifier + modifiers.slice(0, -1).map(m => '.' + m).join('') + '.' + modifier;
|
|
474
517
|
const newItem = {
|
|
@@ -489,8 +532,9 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
|
|
|
489
532
|
}
|
|
490
533
|
else if (hasModifier && isModel) {
|
|
491
534
|
for (const modifier of modelData.globalAttributes ?? []) {
|
|
492
|
-
if (modifiers.includes(modifier.name))
|
|
535
|
+
if (modifiers.includes(modifier.name)) {
|
|
493
536
|
continue;
|
|
537
|
+
}
|
|
494
538
|
const insertText = textWithoutModifier + modifiers.slice(0, -1).map(m => '.' + m).join('') + '.' + modifier.name;
|
|
495
539
|
const newItem = {
|
|
496
540
|
label: modifier.name,
|
|
@@ -15,8 +15,9 @@ function create(ts) {
|
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
17
|
const { template } = virtualCode.sfc;
|
|
18
|
-
if (!template?.ast)
|
|
18
|
+
if (!template?.ast) {
|
|
19
19
|
return;
|
|
20
|
+
}
|
|
20
21
|
const templateStartOffset = template.startTagEnd;
|
|
21
22
|
const result = [];
|
|
22
23
|
for (const node of (0, language_core_1.eachElementNode)(template.ast)) {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { ServicePlugin } from '@volar/language-service';
|
|
2
|
-
export declare function create(ts: typeof import('typescript'),
|
|
1
|
+
import type { ServiceContext, ServicePlugin } from '@volar/language-service';
|
|
2
|
+
export declare function create(ts: typeof import('typescript'), getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined): ServicePlugin;
|
|
@@ -3,15 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.create = void 0;
|
|
4
4
|
const vue = require("@vue/language-core");
|
|
5
5
|
const twoslashReg = /<!--\s*\^\?\s*-->/g;
|
|
6
|
-
function create(ts,
|
|
6
|
+
function create(ts, getTsPluginClient) {
|
|
7
7
|
return {
|
|
8
8
|
name: 'vue-twoslash-queries',
|
|
9
9
|
create(context) {
|
|
10
|
+
const tsPluginClient = getTsPluginClient?.(context);
|
|
10
11
|
return {
|
|
11
12
|
async provideInlayHints(document, range) {
|
|
12
13
|
const [virtualCode, sourceFile] = context.documents.getVirtualCodeByUri(document.uri);
|
|
13
|
-
if (!(sourceFile?.generated?.code instanceof vue.VueGeneratedCode) || virtualCode?.id !== 'template')
|
|
14
|
+
if (!(sourceFile?.generated?.code instanceof vue.VueGeneratedCode) || virtualCode?.id !== 'template') {
|
|
14
15
|
return;
|
|
16
|
+
}
|
|
15
17
|
const hoverOffsets = [];
|
|
16
18
|
const inlayHints = [];
|
|
17
19
|
for (const pointer of document.getText(range).matchAll(twoslashReg)) {
|
|
@@ -19,8 +19,9 @@ function create() {
|
|
|
19
19
|
&& mapping.generatedOffsets[mapping.generatedOffsets.length - 1] + mapping.lengths[mapping.lengths.length - 1] <= end
|
|
20
20
|
&& hint) {
|
|
21
21
|
settings[hint.setting] ??= await context.env.getConfiguration?.(hint.setting) ?? false;
|
|
22
|
-
if (!settings[hint.setting])
|
|
22
|
+
if (!settings[hint.setting]) {
|
|
23
23
|
continue;
|
|
24
|
+
}
|
|
24
25
|
result.push({
|
|
25
26
|
label: hint.label,
|
|
26
27
|
paddingRight: hint.paddingRight,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vue/language-service",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.7",
|
|
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.1.
|
|
20
|
-
"@volar/language-service": "~2.1.
|
|
21
|
-
"@volar/typescript": "~2.1.
|
|
19
|
+
"@volar/language-core": "~2.1.3",
|
|
20
|
+
"@volar/language-service": "~2.1.3",
|
|
21
|
+
"@volar/typescript": "~2.1.3",
|
|
22
22
|
"@vue/compiler-dom": "^3.4.0",
|
|
23
|
-
"@vue/language-core": "2.0.
|
|
23
|
+
"@vue/language-core": "2.0.7",
|
|
24
24
|
"@vue/shared": "^3.4.0",
|
|
25
|
+
"@vue/typescript-plugin": "2.0.7",
|
|
25
26
|
"computeds": "^0.0.1",
|
|
26
27
|
"path-browserify": "^1.0.1",
|
|
27
|
-
"volar-service-css": "0.0.
|
|
28
|
-
"volar-service-emmet": "0.0.
|
|
29
|
-
"volar-service-html": "0.0.
|
|
30
|
-
"volar-service-json": "0.0.
|
|
31
|
-
"volar-service-pug": "0.0.
|
|
32
|
-
"volar-service-pug-beautify": "0.0.
|
|
33
|
-
"volar-service-typescript": "0.0.
|
|
34
|
-
"volar-service-typescript-twoslash-queries": "0.0.
|
|
28
|
+
"volar-service-css": "0.0.34",
|
|
29
|
+
"volar-service-emmet": "0.0.34",
|
|
30
|
+
"volar-service-html": "0.0.34",
|
|
31
|
+
"volar-service-json": "0.0.34",
|
|
32
|
+
"volar-service-pug": "0.0.34",
|
|
33
|
+
"volar-service-pug-beautify": "0.0.34",
|
|
34
|
+
"volar-service-typescript": "0.0.34",
|
|
35
|
+
"volar-service-typescript-twoslash-queries": "0.0.34",
|
|
35
36
|
"vscode-html-languageservice": "^5.1.0",
|
|
36
|
-
"vscode-languageserver-textdocument": "^1.0.11"
|
|
37
|
+
"vscode-languageserver-textdocument": "^1.0.11",
|
|
38
|
+
"vscode-uri": "^3.0.8"
|
|
37
39
|
},
|
|
38
40
|
"devDependencies": {
|
|
39
41
|
"@types/node": "latest",
|
|
40
42
|
"@types/path-browserify": "latest",
|
|
41
|
-
"@volar/kit": "~2.1.
|
|
42
|
-
"
|
|
43
|
-
"vscode-languageserver-protocol": "^3.17.5",
|
|
44
|
-
"vscode-uri": "^3.0.8"
|
|
43
|
+
"@volar/kit": "~2.1.3",
|
|
44
|
+
"vscode-languageserver-protocol": "^3.17.5"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "4a37e8f3ebcf31ecfd2ea627f7611d5990ec5df6"
|
|
47
47
|
}
|