@vue/language-service 3.1.5 → 3.1.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.js +5 -3
- package/lib/htmlFormatter.d.ts +2 -0
- package/lib/htmlFormatter.js +163 -0
- package/lib/nameCasing.d.ts +4 -6
- package/lib/nameCasing.js +62 -73
- package/lib/plugins/css.js +49 -1
- package/lib/plugins/vue-autoinsert-dotvalue.js +27 -27
- package/lib/plugins/vue-document-drop.js +2 -2
- package/lib/plugins/vue-format-per-block.d.ts +2 -0
- package/lib/plugins/vue-format-per-block.js +51 -0
- package/lib/plugins/vue-missing-props-hints.js +2 -2
- package/lib/plugins/vue-scoped-class-links.js +14 -10
- package/lib/plugins/vue-suggest-define-assignment.d.ts +1 -1
- package/lib/plugins/vue-suggest-define-assignment.js +38 -2
- package/lib/plugins/vue-template.d.ts +2 -2
- package/lib/plugins/vue-template.js +220 -41
- package/lib/utils.d.ts +0 -1
- package/lib/utils.js +0 -15
- package/package.json +7 -7
package/index.js
CHANGED
|
@@ -34,6 +34,7 @@ const vue_directive_comments_1 = require("./lib/plugins/vue-directive-comments")
|
|
|
34
34
|
const vue_document_drop_1 = require("./lib/plugins/vue-document-drop");
|
|
35
35
|
const vue_document_highlights_1 = require("./lib/plugins/vue-document-highlights");
|
|
36
36
|
const vue_extract_file_1 = require("./lib/plugins/vue-extract-file");
|
|
37
|
+
const vue_format_per_block_1 = require("./lib/plugins/vue-format-per-block");
|
|
37
38
|
const vue_global_types_error_1 = require("./lib/plugins/vue-global-types-error");
|
|
38
39
|
const vue_inlayhints_1 = require("./lib/plugins/vue-inlayhints");
|
|
39
40
|
const vue_missing_props_hints_1 = require("./lib/plugins/vue-missing-props-hints");
|
|
@@ -52,13 +53,13 @@ function createVueLanguageServicePlugins(ts, client = new Proxy({}, {
|
|
|
52
53
|
return [
|
|
53
54
|
(0, volar_service_json_1.create)(),
|
|
54
55
|
(0, volar_service_pug_beautify_1.create)(),
|
|
56
|
+
(0, vue_format_per_block_1.create)(),
|
|
55
57
|
(0, vue_autoinsert_space_1.create)(),
|
|
56
58
|
(0, vue_compiler_dom_errors_1.create)(),
|
|
57
59
|
(0, vue_directive_comments_1.create)(),
|
|
58
60
|
(0, vue_global_types_error_1.create)(),
|
|
59
61
|
(0, vue_scoped_class_links_1.create)(),
|
|
60
62
|
(0, vue_sfc_1.create)(),
|
|
61
|
-
(0, vue_suggest_define_assignment_1.create)(),
|
|
62
63
|
(0, vue_template_ref_links_1.create)(),
|
|
63
64
|
(0, volar_service_emmet_1.create)({
|
|
64
65
|
mappedLanguages: {
|
|
@@ -67,6 +68,7 @@ function createVueLanguageServicePlugins(ts, client = new Proxy({}, {
|
|
|
67
68
|
},
|
|
68
69
|
}),
|
|
69
70
|
// TS related plugins
|
|
71
|
+
(0, vue_suggest_define_assignment_1.create)(ts),
|
|
70
72
|
(0, docCommentTemplate_1.create)(ts),
|
|
71
73
|
(0, syntactic_1.create)(ts),
|
|
72
74
|
(0, vue_inlayhints_1.create)(ts),
|
|
@@ -79,8 +81,8 @@ function createVueLanguageServicePlugins(ts, client = new Proxy({}, {
|
|
|
79
81
|
(0, vue_document_highlights_1.create)(client),
|
|
80
82
|
(0, vue_extract_file_1.create)(ts, client),
|
|
81
83
|
(0, vue_missing_props_hints_1.create)(client),
|
|
82
|
-
(0, vue_template_1.create)('html', client),
|
|
83
|
-
(0, vue_template_1.create)('jade', client),
|
|
84
|
+
(0, vue_template_1.create)(ts, 'html', client),
|
|
85
|
+
(0, vue_template_1.create)(ts, 'jade', client),
|
|
84
86
|
(0, vue_twoslash_queries_1.create)(client),
|
|
85
87
|
];
|
|
86
88
|
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.format = format;
|
|
4
|
+
// @ts-expect-error
|
|
5
|
+
const beautify = require("vscode-html-languageservice/lib/umd/beautify/beautify-html.js");
|
|
6
|
+
// @ts-expect-error
|
|
7
|
+
const strings = require("vscode-html-languageservice/lib/umd/utils/strings.js");
|
|
8
|
+
/*
|
|
9
|
+
* original file: https://github.com/microsoft/vscode-html-languageservice/blob/main/src/services/htmlFormatter.ts
|
|
10
|
+
* commit: a134f3050c22fe80954241467cd429811792a81d (2024-03-22)
|
|
11
|
+
* purpose: override to add void_elements option
|
|
12
|
+
*/
|
|
13
|
+
/*---------------------------------------------------------------------------------------------
|
|
14
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
15
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
16
|
+
*--------------------------------------------------------------------------------------------*/
|
|
17
|
+
const vscode_html_languageservice_1 = require("vscode-html-languageservice");
|
|
18
|
+
function format(document, range, options, voidElements) {
|
|
19
|
+
let value = document.getText();
|
|
20
|
+
let includesEnd = true;
|
|
21
|
+
let initialIndentLevel = 0;
|
|
22
|
+
const tabSize = options.tabSize || 4;
|
|
23
|
+
if (range) {
|
|
24
|
+
let startOffset = document.offsetAt(range.start);
|
|
25
|
+
// include all leading whitespace iff at the beginning of the line
|
|
26
|
+
let extendedStart = startOffset;
|
|
27
|
+
while (extendedStart > 0 && isWhitespace(value, extendedStart - 1)) {
|
|
28
|
+
extendedStart--;
|
|
29
|
+
}
|
|
30
|
+
if (extendedStart === 0 || isEOL(value, extendedStart - 1)) {
|
|
31
|
+
startOffset = extendedStart;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
// else keep at least one whitespace
|
|
35
|
+
if (extendedStart < startOffset) {
|
|
36
|
+
startOffset = extendedStart + 1;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// include all following whitespace until the end of the line
|
|
40
|
+
let endOffset = document.offsetAt(range.end);
|
|
41
|
+
let extendedEnd = endOffset;
|
|
42
|
+
while (extendedEnd < value.length && isWhitespace(value, extendedEnd)) {
|
|
43
|
+
extendedEnd++;
|
|
44
|
+
}
|
|
45
|
+
if (extendedEnd === value.length || isEOL(value, extendedEnd)) {
|
|
46
|
+
endOffset = extendedEnd;
|
|
47
|
+
}
|
|
48
|
+
range = vscode_html_languageservice_1.Range.create(document.positionAt(startOffset), document.positionAt(endOffset));
|
|
49
|
+
// Do not modify if substring starts in inside an element
|
|
50
|
+
// Ending inside an element is fine as it doesn't cause formatting errors
|
|
51
|
+
const firstHalf = value.substring(0, startOffset);
|
|
52
|
+
if (new RegExp(/.*[<][^>]*$/).test(firstHalf)) {
|
|
53
|
+
// return without modification
|
|
54
|
+
value = value.substring(startOffset, endOffset);
|
|
55
|
+
return [{
|
|
56
|
+
range: range,
|
|
57
|
+
newText: value,
|
|
58
|
+
}];
|
|
59
|
+
}
|
|
60
|
+
includesEnd = endOffset === value.length;
|
|
61
|
+
value = value.substring(startOffset, endOffset);
|
|
62
|
+
if (startOffset !== 0) {
|
|
63
|
+
const startOfLineOffset = document.offsetAt(vscode_html_languageservice_1.Position.create(range.start.line, 0));
|
|
64
|
+
initialIndentLevel = computeIndentLevel(document.getText(), startOfLineOffset, options);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
range = vscode_html_languageservice_1.Range.create(vscode_html_languageservice_1.Position.create(0, 0), document.positionAt(value.length));
|
|
69
|
+
}
|
|
70
|
+
const htmlOptions = {
|
|
71
|
+
indent_size: tabSize,
|
|
72
|
+
indent_char: options.insertSpaces ? ' ' : '\t',
|
|
73
|
+
indent_empty_lines: getFormatOption(options, 'indentEmptyLines', false),
|
|
74
|
+
wrap_line_length: getFormatOption(options, 'wrapLineLength', 120),
|
|
75
|
+
unformatted: getTagsFormatOption(options, 'unformatted', void 0),
|
|
76
|
+
content_unformatted: getTagsFormatOption(options, 'contentUnformatted', void 0),
|
|
77
|
+
indent_inner_html: getFormatOption(options, 'indentInnerHtml', false),
|
|
78
|
+
preserve_newlines: getFormatOption(options, 'preserveNewLines', true),
|
|
79
|
+
max_preserve_newlines: getFormatOption(options, 'maxPreserveNewLines', 32786),
|
|
80
|
+
indent_handlebars: getFormatOption(options, 'indentHandlebars', false),
|
|
81
|
+
end_with_newline: includesEnd && getFormatOption(options, 'endWithNewline', false),
|
|
82
|
+
extra_liners: getTagsFormatOption(options, 'extraLiners', void 0),
|
|
83
|
+
wrap_attributes: getFormatOption(options, 'wrapAttributes', 'auto'),
|
|
84
|
+
wrap_attributes_indent_size: getFormatOption(options, 'wrapAttributesIndentSize', void 0),
|
|
85
|
+
eol: '\n',
|
|
86
|
+
indent_scripts: getFormatOption(options, 'indentScripts', 'normal'),
|
|
87
|
+
templating: getTemplatingFormatOption(options, 'all'),
|
|
88
|
+
unformatted_content_delimiter: getFormatOption(options, 'unformattedContentDelimiter', ''),
|
|
89
|
+
...voidElements !== undefined && { void_elements: voidElements },
|
|
90
|
+
};
|
|
91
|
+
let result = beautify.html_beautify(trimLeft(value), htmlOptions);
|
|
92
|
+
if (initialIndentLevel > 0) {
|
|
93
|
+
const indent = options.insertSpaces
|
|
94
|
+
? strings.repeat(' ', tabSize * initialIndentLevel)
|
|
95
|
+
: strings.repeat('\t', initialIndentLevel);
|
|
96
|
+
result = result.split('\n').join('\n' + indent);
|
|
97
|
+
if (range.start.character === 0) {
|
|
98
|
+
result = indent + result; // keep the indent
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return [{
|
|
102
|
+
range: range,
|
|
103
|
+
newText: result,
|
|
104
|
+
}];
|
|
105
|
+
}
|
|
106
|
+
function trimLeft(str) {
|
|
107
|
+
return str.replace(/^\s+/, '');
|
|
108
|
+
}
|
|
109
|
+
function getFormatOption(options, key, dflt) {
|
|
110
|
+
if (options && options.hasOwnProperty(key)) {
|
|
111
|
+
const value = options[key];
|
|
112
|
+
if (value !== null) {
|
|
113
|
+
return value;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return dflt;
|
|
117
|
+
}
|
|
118
|
+
function getTagsFormatOption(options, key, dflt) {
|
|
119
|
+
const list = getFormatOption(options, key, null);
|
|
120
|
+
if (typeof list === 'string') {
|
|
121
|
+
if (list.length > 0) {
|
|
122
|
+
return list.split(',').map(t => t.trim().toLowerCase());
|
|
123
|
+
}
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
return dflt;
|
|
127
|
+
}
|
|
128
|
+
function getTemplatingFormatOption(options, dflt) {
|
|
129
|
+
const value = getFormatOption(options, 'templating', dflt);
|
|
130
|
+
if (value === true) {
|
|
131
|
+
return ['auto'];
|
|
132
|
+
}
|
|
133
|
+
if (value === false || value === dflt || Array.isArray(value) === false) {
|
|
134
|
+
return ['none'];
|
|
135
|
+
}
|
|
136
|
+
return value;
|
|
137
|
+
}
|
|
138
|
+
function computeIndentLevel(content, offset, options) {
|
|
139
|
+
let i = offset;
|
|
140
|
+
let nChars = 0;
|
|
141
|
+
const tabSize = options.tabSize || 4;
|
|
142
|
+
while (i < content.length) {
|
|
143
|
+
const ch = content.charAt(i);
|
|
144
|
+
if (ch === ' ') {
|
|
145
|
+
nChars++;
|
|
146
|
+
}
|
|
147
|
+
else if (ch === '\t') {
|
|
148
|
+
nChars += tabSize;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
i++;
|
|
154
|
+
}
|
|
155
|
+
return Math.floor(nChars / tabSize);
|
|
156
|
+
}
|
|
157
|
+
function isEOL(text, offset) {
|
|
158
|
+
return '\r\n'.indexOf(text.charAt(offset)) !== -1;
|
|
159
|
+
}
|
|
160
|
+
function isWhitespace(text, offset) {
|
|
161
|
+
return ' \t'.indexOf(text.charAt(offset)) !== -1;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=htmlFormatter.js.map
|
package/lib/nameCasing.d.ts
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import type { LanguageServiceContext } from '@volar/language-service';
|
|
2
2
|
import type { URI } from 'vscode-uri';
|
|
3
|
-
export declare enum TagNameCasing {
|
|
3
|
+
export declare const enum TagNameCasing {
|
|
4
4
|
Kebab = 0,
|
|
5
5
|
Pascal = 1
|
|
6
6
|
}
|
|
7
|
-
export declare enum AttrNameCasing {
|
|
7
|
+
export declare const enum AttrNameCasing {
|
|
8
8
|
Kebab = 0,
|
|
9
9
|
Camel = 1
|
|
10
10
|
}
|
|
11
|
-
export declare function
|
|
12
|
-
|
|
13
|
-
attr: AttrNameCasing | undefined;
|
|
14
|
-
}>;
|
|
11
|
+
export declare function getTagNameCasing(context: LanguageServiceContext, uri: URI): Promise<TagNameCasing | undefined>;
|
|
12
|
+
export declare function getAttrNameCasing(context: LanguageServiceContext, uri: URI): Promise<AttrNameCasing | undefined>;
|
package/lib/nameCasing.js
CHANGED
|
@@ -1,71 +1,62 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.
|
|
3
|
+
exports.getTagNameCasing = getTagNameCasing;
|
|
4
|
+
exports.getAttrNameCasing = getAttrNameCasing;
|
|
5
5
|
const language_core_1 = require("@vue/language-core");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
})(AttrNameCasing || (exports.AttrNameCasing = AttrNameCasing = {}));
|
|
16
|
-
async function checkCasing(context, uri) {
|
|
17
|
-
const detected = detect(context, uri);
|
|
18
|
-
const [attr, tag] = await Promise.all([
|
|
19
|
-
context.env.getConfiguration?.('vue.suggest.propNameCasing', uri.toString()),
|
|
20
|
-
context.env.getConfiguration?.('vue.suggest.componentNameCasing', uri.toString()),
|
|
21
|
-
]);
|
|
22
|
-
const tagNameCasing = detected.tag.length === 1 && (tag === 'preferPascalCase' || tag === 'preferKebabCase')
|
|
23
|
-
? detected.tag[0]
|
|
24
|
-
: (tag === 'preferKebabCase' || tag === 'alwaysKebabCase')
|
|
25
|
-
? TagNameCasing.Kebab
|
|
26
|
-
: TagNameCasing.Pascal;
|
|
27
|
-
const attrNameCasing = detected.attr.length === 1 && (attr === 'preferCamelCase' || attr === 'preferKebabCase')
|
|
28
|
-
? detected.attr[0]
|
|
29
|
-
: (attr === 'preferCamelCase' || attr === 'alwaysCamelCase')
|
|
30
|
-
? AttrNameCasing.Camel
|
|
31
|
-
: AttrNameCasing.Kebab;
|
|
32
|
-
return {
|
|
33
|
-
tag: tagNameCasing,
|
|
34
|
-
attr: attrNameCasing,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
const cache = new WeakMap();
|
|
38
|
-
function detect(context, uri) {
|
|
6
|
+
const collectCache = new WeakMap();
|
|
7
|
+
async function getTagNameCasing(context, uri) {
|
|
8
|
+
const config = await context.env.getConfiguration?.('vue.suggest.componentNameCasing', uri.toString());
|
|
9
|
+
if (config === 'alwaysKebabCase') {
|
|
10
|
+
return 0 /* TagNameCasing.Kebab */;
|
|
11
|
+
}
|
|
12
|
+
if (config === 'alwaysPascalCase') {
|
|
13
|
+
return 1 /* TagNameCasing.Pascal */;
|
|
14
|
+
}
|
|
39
15
|
const root = context.language.scripts.get(uri)?.generated?.root;
|
|
40
|
-
if (
|
|
41
|
-
|
|
16
|
+
if (root instanceof language_core_1.VueVirtualCode) {
|
|
17
|
+
const detectedCasings = detectTagCasing(root);
|
|
18
|
+
if (detectedCasings.length === 1) {
|
|
19
|
+
return detectedCasings[0];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (config === 'preferKebabCase') {
|
|
23
|
+
return 0 /* TagNameCasing.Kebab */;
|
|
42
24
|
}
|
|
43
|
-
return
|
|
44
|
-
tag: detectTagCasing(root),
|
|
45
|
-
attr: detectAttrCasing(root),
|
|
46
|
-
};
|
|
25
|
+
return 1 /* TagNameCasing.Pascal */;
|
|
47
26
|
}
|
|
48
|
-
function
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
|
|
27
|
+
async function getAttrNameCasing(context, uri) {
|
|
28
|
+
const config = await context.env.getConfiguration?.('vue.suggest.propNameCasing', uri.toString());
|
|
29
|
+
if (config === 'alwaysKebabCase') {
|
|
30
|
+
return 0 /* AttrNameCasing.Kebab */;
|
|
31
|
+
}
|
|
32
|
+
if (config === 'alwaysCamelCase') {
|
|
33
|
+
return 1 /* AttrNameCasing.Camel */;
|
|
52
34
|
}
|
|
53
|
-
|
|
54
|
-
|
|
35
|
+
const root = context.language.scripts.get(uri)?.generated?.root;
|
|
36
|
+
if (root instanceof language_core_1.VueVirtualCode) {
|
|
37
|
+
const detectedCasings = detectAttrCasing(root);
|
|
38
|
+
if (detectedCasings.length === 1) {
|
|
39
|
+
return detectedCasings[0];
|
|
40
|
+
}
|
|
55
41
|
}
|
|
42
|
+
if (config === 'preferKebabCase') {
|
|
43
|
+
return 0 /* AttrNameCasing.Kebab */;
|
|
44
|
+
}
|
|
45
|
+
return 1 /* AttrNameCasing.Camel */;
|
|
46
|
+
}
|
|
47
|
+
function detectAttrCasing(code) {
|
|
48
|
+
const tags = collectTagsWithCache(code);
|
|
56
49
|
const result = new Set();
|
|
57
|
-
for (const [, attrs] of tags
|
|
50
|
+
for (const [, [_, attrs]] of tags) {
|
|
58
51
|
for (const attr of attrs) {
|
|
59
|
-
// attrName
|
|
60
52
|
if (attr !== (0, language_core_1.hyphenateTag)(attr)) {
|
|
61
|
-
result.add(AttrNameCasing.Camel);
|
|
53
|
+
result.add(1 /* AttrNameCasing.Camel */);
|
|
62
54
|
break;
|
|
63
55
|
}
|
|
64
56
|
}
|
|
65
57
|
for (const attr of attrs) {
|
|
66
|
-
// attr-name
|
|
67
58
|
if (attr.includes('-')) {
|
|
68
|
-
result.add(AttrNameCasing.Kebab);
|
|
59
|
+
result.add(0 /* AttrNameCasing.Kebab */);
|
|
69
60
|
break;
|
|
70
61
|
}
|
|
71
62
|
}
|
|
@@ -73,39 +64,37 @@ function detectAttrCasing(code) {
|
|
|
73
64
|
return [...result];
|
|
74
65
|
}
|
|
75
66
|
function detectTagCasing(code) {
|
|
76
|
-
|
|
77
|
-
if (cache.has(code)) {
|
|
78
|
-
tags = cache.get(code);
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
cache.set(code, tags = collectTags(code));
|
|
82
|
-
}
|
|
67
|
+
const tags = collectTagsWithCache(code);
|
|
83
68
|
const result = new Set();
|
|
84
|
-
for (const [tag] of tags
|
|
69
|
+
for (const [tag, [tagType]] of tags) {
|
|
70
|
+
if (tagType === 0
|
|
71
|
+
|| tagType === 3) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
85
74
|
if (tag !== (0, language_core_1.hyphenateTag)(tag)) {
|
|
86
|
-
|
|
87
|
-
result.add(TagNameCasing.Pascal);
|
|
75
|
+
result.add(1 /* TagNameCasing.Pascal */);
|
|
88
76
|
}
|
|
89
77
|
else {
|
|
90
|
-
|
|
91
|
-
result.add(TagNameCasing.Kebab);
|
|
78
|
+
result.add(0 /* TagNameCasing.Kebab */);
|
|
92
79
|
}
|
|
93
80
|
}
|
|
94
81
|
return [...result];
|
|
95
82
|
}
|
|
96
|
-
function
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return undefined;
|
|
83
|
+
function collectTagsWithCache(code) {
|
|
84
|
+
let cache = collectCache.get(code);
|
|
85
|
+
if (!cache) {
|
|
86
|
+
const ast = code.sfc.template?.ast;
|
|
87
|
+
cache = ast ? collectTags(ast) : new Map();
|
|
88
|
+
collectCache.set(code, cache);
|
|
103
89
|
}
|
|
90
|
+
return cache;
|
|
91
|
+
}
|
|
92
|
+
function collectTags(ast) {
|
|
104
93
|
const tags = new Map();
|
|
105
94
|
for (const node of (0, language_core_1.forEachElementNode)(ast)) {
|
|
106
95
|
let tag = tags.get(node.tag);
|
|
107
96
|
if (!tag) {
|
|
108
|
-
tags.set(node.tag, tag = []);
|
|
97
|
+
tags.set(node.tag, tag = [node.tagType, []]);
|
|
109
98
|
}
|
|
110
99
|
for (const prop of node.props) {
|
|
111
100
|
let name;
|
|
@@ -118,7 +107,7 @@ function collectTags(root) {
|
|
|
118
107
|
name = prop.name;
|
|
119
108
|
}
|
|
120
109
|
if (name !== undefined) {
|
|
121
|
-
tag.push(name);
|
|
110
|
+
tag[1].push(name);
|
|
122
111
|
}
|
|
123
112
|
}
|
|
124
113
|
}
|
package/lib/plugins/css.js
CHANGED
|
@@ -3,12 +3,42 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.create = create;
|
|
4
4
|
const language_core_1 = require("@vue/language-core");
|
|
5
5
|
const volar_service_css_1 = require("volar-service-css");
|
|
6
|
+
const vscode_uri_1 = require("vscode-uri");
|
|
6
7
|
const utils_1 = require("../utils");
|
|
7
8
|
function create({ resolveModuleName }) {
|
|
9
|
+
let modulePathCache;
|
|
8
10
|
const baseService = (0, volar_service_css_1.create)({
|
|
9
11
|
getDocumentContext(context) {
|
|
10
12
|
return {
|
|
11
|
-
resolveReference
|
|
13
|
+
resolveReference(ref, base) {
|
|
14
|
+
let baseUri = vscode_uri_1.URI.parse(base);
|
|
15
|
+
const decoded = context.decodeEmbeddedDocumentUri(baseUri);
|
|
16
|
+
if (decoded) {
|
|
17
|
+
baseUri = decoded[0];
|
|
18
|
+
}
|
|
19
|
+
if (modulePathCache
|
|
20
|
+
&& baseUri.scheme === 'file'
|
|
21
|
+
&& !ref.startsWith('./')
|
|
22
|
+
&& !ref.startsWith('../')) {
|
|
23
|
+
const map = modulePathCache;
|
|
24
|
+
if (!map.has(ref)) {
|
|
25
|
+
const fileName = baseUri.fsPath.replace(/\\/g, '/');
|
|
26
|
+
const promise = resolveModuleName(fileName, ref);
|
|
27
|
+
map.set(ref, promise);
|
|
28
|
+
if (promise instanceof Promise) {
|
|
29
|
+
promise.then(res => map.set(ref, res));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const cached = modulePathCache.get(ref);
|
|
33
|
+
if (cached instanceof Promise) {
|
|
34
|
+
throw cached;
|
|
35
|
+
}
|
|
36
|
+
if (cached) {
|
|
37
|
+
return cached;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return (0, volar_service_css_1.resolveReference)(ref, baseUri, context.env.workspaceFolders);
|
|
41
|
+
},
|
|
12
42
|
};
|
|
13
43
|
},
|
|
14
44
|
scssDocumentSelector: ['scss', 'postcss'],
|
|
@@ -49,6 +79,24 @@ function create({ resolveModuleName }) {
|
|
|
49
79
|
return cssLs.prepareRename(document, position, stylesheet);
|
|
50
80
|
});
|
|
51
81
|
},
|
|
82
|
+
async provideDocumentLinks(document, token) {
|
|
83
|
+
modulePathCache = new Map();
|
|
84
|
+
while (true) {
|
|
85
|
+
try {
|
|
86
|
+
const result = await baseServiceInstance.provideDocumentLinks?.(document, token);
|
|
87
|
+
modulePathCache = undefined;
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
if (e instanceof Promise) {
|
|
92
|
+
await e;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
throw e;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
},
|
|
52
100
|
};
|
|
53
101
|
function isWithinNavigationVirtualCode(document, position) {
|
|
54
102
|
const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
|
|
@@ -44,7 +44,7 @@ function create(ts, { isRefAtPosition }) {
|
|
|
44
44
|
if (sourceOffset < startTagEnd || sourceOffset > endTagStart) {
|
|
45
45
|
continue;
|
|
46
46
|
}
|
|
47
|
-
if (
|
|
47
|
+
if (shouldSkip(ts, ast, sourceOffset - startTagEnd, false)) {
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -68,7 +68,7 @@ function isCharacterTyping(document, change) {
|
|
|
68
68
|
}
|
|
69
69
|
return charReg.test(lastCharacter) && !charReg.test(nextCharacter);
|
|
70
70
|
}
|
|
71
|
-
function
|
|
71
|
+
function shouldSkip(ts, node, pos, allowAccessDotValue) {
|
|
72
72
|
if (ts.isVariableDeclaration(node) && pos >= node.name.getFullStart() && pos <= node.name.getEnd()) {
|
|
73
73
|
return true;
|
|
74
74
|
}
|
|
@@ -100,45 +100,45 @@ function isBlacklistNode(ts, node, pos, allowAccessDotValue) {
|
|
|
100
100
|
else if (ts.isCallExpression(node)
|
|
101
101
|
&& ts.isIdentifier(node.expression)
|
|
102
102
|
&& isWatchOrUseFunction(node.expression.text)
|
|
103
|
-
&& isTopLevelArgOrArrayTopLevelItemItem(node)) {
|
|
103
|
+
&& isTopLevelArgOrArrayTopLevelItemItem(ts, node, pos)) {
|
|
104
104
|
return true;
|
|
105
105
|
}
|
|
106
106
|
else {
|
|
107
|
-
let
|
|
107
|
+
let _shouldSkip = false;
|
|
108
108
|
node.forEachChild(node => {
|
|
109
|
-
if (
|
|
109
|
+
if (_shouldSkip) {
|
|
110
110
|
return;
|
|
111
111
|
}
|
|
112
112
|
if (pos >= node.getFullStart() && pos <= node.getEnd()) {
|
|
113
|
-
if (
|
|
114
|
-
|
|
113
|
+
if (shouldSkip(ts, node, pos, allowAccessDotValue)) {
|
|
114
|
+
_shouldSkip = true;
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
});
|
|
118
|
-
return
|
|
118
|
+
return _shouldSkip;
|
|
119
119
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
120
|
+
}
|
|
121
|
+
function isWatchOrUseFunction(fnName) {
|
|
122
|
+
return fnName === 'watch'
|
|
123
|
+
|| fnName === 'unref'
|
|
124
|
+
|| fnName === 'triggerRef'
|
|
125
|
+
|| fnName === 'isRef'
|
|
126
|
+
|| (0, language_core_1.hyphenateAttr)(fnName).startsWith('use-');
|
|
127
|
+
}
|
|
128
|
+
function isTopLevelArgOrArrayTopLevelItemItem(ts, node, pos) {
|
|
129
|
+
for (const arg of node.arguments) {
|
|
130
|
+
if (pos >= arg.getFullStart() && pos <= arg.getEnd()) {
|
|
131
|
+
if (ts.isIdentifier(arg)) {
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
if (ts.isArrayLiteralExpression(arg)) {
|
|
135
|
+
for (const el of arg.elements) {
|
|
136
|
+
if (pos >= el.getFullStart() && pos <= el.getEnd()) {
|
|
137
|
+
return ts.isIdentifier(el);
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
|
-
return false;
|
|
141
140
|
}
|
|
141
|
+
return false;
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
}
|
|
@@ -39,7 +39,7 @@ function create(ts, { getImportPathForFile }) {
|
|
|
39
39
|
if (!script) {
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
|
-
const
|
|
42
|
+
const tagNameCasing = await (0, nameCasing_1.getTagNameCasing)(context, info.script.id);
|
|
43
43
|
const baseName = path_browserify_1.posix.basename(importUri);
|
|
44
44
|
const newName = (0, shared_1.capitalize)((0, shared_1.camelize)(baseName.slice(0, baseName.lastIndexOf('.'))));
|
|
45
45
|
const additionalEdit = {};
|
|
@@ -90,7 +90,7 @@ function create(ts, { getImportPathForFile }) {
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
return {
|
|
93
|
-
insertText: `<${
|
|
93
|
+
insertText: `<${tagNameCasing === 0 /* TagNameCasing.Kebab */ ? (0, shared_1.hyphenate)(newName) : newName}$0 />`,
|
|
94
94
|
insertTextFormat: 2,
|
|
95
95
|
additionalEdit,
|
|
96
96
|
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.create = create;
|
|
4
|
+
const vscode_uri_1 = require("vscode-uri");
|
|
5
|
+
function create() {
|
|
6
|
+
return {
|
|
7
|
+
name: 'vue-format-per-block',
|
|
8
|
+
capabilities: {
|
|
9
|
+
documentFormattingProvider: true,
|
|
10
|
+
documentOnTypeFormattingProvider: {
|
|
11
|
+
triggerCharacters: [],
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
create(context) {
|
|
15
|
+
return {
|
|
16
|
+
async provideDocumentFormattingEdits(document) {
|
|
17
|
+
if (await shouldSkip(document)) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
return undefined;
|
|
21
|
+
},
|
|
22
|
+
async provideOnTypeFormattingEdits(document) {
|
|
23
|
+
if (await shouldSkip(document)) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
async function shouldSkip(document) {
|
|
30
|
+
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(document.uri));
|
|
31
|
+
if (!decoded) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
const [, embeddedCodeId] = decoded;
|
|
35
|
+
if (embeddedCodeId === 'script_raw' || embeddedCodeId === 'scriptsetup_raw') {
|
|
36
|
+
return await context.env.getConfiguration?.('vue.format.script.enabled') === false;
|
|
37
|
+
}
|
|
38
|
+
if (embeddedCodeId.startsWith('style_')) {
|
|
39
|
+
return await context.env.getConfiguration?.('vue.format.style.enabled') === false;
|
|
40
|
+
}
|
|
41
|
+
if (embeddedCodeId === 'template'
|
|
42
|
+
|| embeddedCodeId.startsWith('template_inline_ts_')
|
|
43
|
+
|| embeddedCodeId === 'root_tags') {
|
|
44
|
+
return await context.env.getConfiguration?.('vue.format.template.enabled') === false;
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=vue-format-per-block.js.map
|
|
@@ -28,7 +28,7 @@ function create({ getComponentNames, getElementNames, getComponentProps }) {
|
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
30
|
const result = [];
|
|
31
|
-
const
|
|
31
|
+
const attrNameCasing = await (0, nameCasing_1.getAttrNameCasing)(context, info.script.id);
|
|
32
32
|
const components = await getComponentNames(info.root.fileName) ?? [];
|
|
33
33
|
const componentProps = new Map();
|
|
34
34
|
intrinsicElementNames ??= new Set(await getElementNames(info.root.fileName) ?? []);
|
|
@@ -113,7 +113,7 @@ function create({ getComponentNames, getElementNames, getComponentProps }) {
|
|
|
113
113
|
start: document.positionAt(current.labelOffset),
|
|
114
114
|
end: document.positionAt(current.labelOffset),
|
|
115
115
|
},
|
|
116
|
-
newText: ` :${
|
|
116
|
+
newText: ` :${attrNameCasing === 0 /* AttrNameCasing.Kebab */ ? (0, language_core_1.hyphenateAttr)(requiredProp) : requiredProp}=`,
|
|
117
117
|
}],
|
|
118
118
|
});
|
|
119
119
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.create = create;
|
|
4
|
-
const
|
|
4
|
+
const styleScopedClasses_1 = require("@vue/language-core/lib/codegen/template/styleScopedClasses");
|
|
5
5
|
const utils_1 = require("../utils");
|
|
6
6
|
function create() {
|
|
7
7
|
return {
|
|
@@ -17,17 +17,21 @@ function create() {
|
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
const { sfc } = info.root;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
if (!sfc.template) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const { resolveStyleClassNames } = info.root.vueCompilerOptions;
|
|
24
|
+
if (!resolveStyleClassNames) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const scopedClasses = styleScopedClasses_1.references.get(sfc.template)?.[1] ?? [];
|
|
23
28
|
const styleClasses = new Map();
|
|
24
|
-
for (
|
|
25
|
-
|
|
26
|
-
if (option !== true && !(option === 'scoped' && style.scoped)) {
|
|
29
|
+
for (const style of sfc.styles) {
|
|
30
|
+
if (!(resolveStyleClassNames === true || style.scoped)) {
|
|
27
31
|
continue;
|
|
28
32
|
}
|
|
29
|
-
const styleDocumentUri = context.encodeEmbeddedDocumentUri(info.script.id,
|
|
30
|
-
const styleVirtualCode = info.script.generated.embeddedCodes.get(
|
|
33
|
+
const styleDocumentUri = context.encodeEmbeddedDocumentUri(info.script.id, style.name);
|
|
34
|
+
const styleVirtualCode = info.script.generated.embeddedCodes.get(style.name);
|
|
31
35
|
if (!styleVirtualCode) {
|
|
32
36
|
continue;
|
|
33
37
|
}
|
|
@@ -43,7 +47,7 @@ function create() {
|
|
|
43
47
|
styleClasses.get(text).push(target);
|
|
44
48
|
}
|
|
45
49
|
}
|
|
46
|
-
return scopedClasses.flatMap((
|
|
50
|
+
return scopedClasses.flatMap(([className, offset]) => {
|
|
47
51
|
const range = {
|
|
48
52
|
start: document.positionAt(offset),
|
|
49
53
|
end: document.positionAt(offset + className.length),
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { LanguageServicePlugin } from '@volar/language-service';
|
|
2
|
-
export declare function create(): LanguageServicePlugin;
|
|
2
|
+
export declare function create(ts: typeof import('typescript')): LanguageServicePlugin;
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.create = create;
|
|
4
4
|
const language_core_1 = require("@vue/language-core");
|
|
5
|
+
const vscode_uri_1 = require("vscode-uri");
|
|
5
6
|
const utils_1 = require("../utils");
|
|
6
|
-
|
|
7
|
+
const documentToSourceFile = new WeakMap();
|
|
8
|
+
function create(ts) {
|
|
7
9
|
return {
|
|
8
10
|
name: 'vue-suggest-define-assignment',
|
|
9
11
|
capabilities: {
|
|
@@ -12,7 +14,7 @@ function create() {
|
|
|
12
14
|
create(context) {
|
|
13
15
|
return {
|
|
14
16
|
isAdditionalCompletion: true,
|
|
15
|
-
async provideCompletionItems(document) {
|
|
17
|
+
async provideCompletionItems(document, position) {
|
|
16
18
|
const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
|
|
17
19
|
if (!info?.code.id.startsWith('script_')) {
|
|
18
20
|
return;
|
|
@@ -28,6 +30,10 @@ function create() {
|
|
|
28
30
|
if (!scriptSetup || !scriptSetupRanges) {
|
|
29
31
|
return;
|
|
30
32
|
}
|
|
33
|
+
const sourceFile = getSourceFile(ts, document);
|
|
34
|
+
if (shouldSkip(ts, sourceFile, document.offsetAt(position))) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
31
37
|
const result = [];
|
|
32
38
|
const mappings = [...context.language.maps.forEach(info.code)];
|
|
33
39
|
addDefineCompletionItem(scriptSetupRanges.defineProps?.statement, scriptSetupRanges.withDefaults?.exp ?? scriptSetupRanges.defineProps?.exp, 'props');
|
|
@@ -70,4 +76,34 @@ function create() {
|
|
|
70
76
|
},
|
|
71
77
|
};
|
|
72
78
|
}
|
|
79
|
+
function shouldSkip(ts, node, pos) {
|
|
80
|
+
if (ts.isStringLiteral(node) && pos >= node.getFullStart() && pos <= node.getEnd()) {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
else if (ts.isTemplateLiteral(node) && pos >= node.getFullStart() && pos <= node.getEnd()) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
let _shouldSkip = false;
|
|
88
|
+
node.forEachChild(node => {
|
|
89
|
+
if (_shouldSkip) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (pos >= node.getFullStart() && pos <= node.getEnd()) {
|
|
93
|
+
if (shouldSkip(ts, node, pos)) {
|
|
94
|
+
_shouldSkip = true;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
return _shouldSkip;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function getSourceFile(ts, document) {
|
|
102
|
+
let sourceFile = documentToSourceFile.get(document);
|
|
103
|
+
if (!sourceFile) {
|
|
104
|
+
sourceFile = ts.createSourceFile(vscode_uri_1.URI.parse(document.uri).path, document.getText(), ts.ScriptTarget.Latest);
|
|
105
|
+
documentToSourceFile.set(document, sourceFile);
|
|
106
|
+
}
|
|
107
|
+
return sourceFile;
|
|
108
|
+
}
|
|
73
109
|
//# sourceMappingURL=vue-suggest-define-assignment.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type
|
|
2
|
-
export declare function create(languageId: 'html' | 'jade', { getComponentNames, getComponentProps, getComponentEvents, getComponentDirectives, getComponentSlots, getElementAttrs, resolveModuleName, }: import('@vue/typescript-plugin/lib/requests').Requests): LanguageServicePlugin;
|
|
1
|
+
import { type LanguageServicePlugin } from '@volar/language-service';
|
|
2
|
+
export declare function create(ts: typeof import('typescript'), languageId: 'html' | 'jade', { getComponentNames, getComponentProps, getComponentEvents, getComponentDirectives, getComponentSlots, getElementAttrs, resolveModuleName, getAutoImportSuggestions, resolveAutoImportCompletionEntry, }: import('@vue/typescript-plugin/lib/requests').Requests): LanguageServicePlugin;
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.create = create;
|
|
4
|
+
const language_service_1 = require("@volar/language-service");
|
|
5
|
+
const featureWorkers_1 = require("@volar/language-service/lib/utils/featureWorkers");
|
|
4
6
|
const language_core_1 = require("@vue/language-core");
|
|
5
7
|
const shared_1 = require("@vue/shared");
|
|
6
8
|
const volar_service_html_1 = require("volar-service-html");
|
|
7
9
|
const volar_service_pug_1 = require("volar-service-pug");
|
|
10
|
+
const getFormatCodeSettings_js_1 = require("volar-service-typescript/lib/configs/getFormatCodeSettings.js");
|
|
11
|
+
const getUserPreferences_js_1 = require("volar-service-typescript/lib/configs/getUserPreferences.js");
|
|
12
|
+
const lspConverters_js_1 = require("volar-service-typescript/lib/utils/lspConverters.js");
|
|
8
13
|
const html = require("vscode-html-languageservice");
|
|
9
14
|
const vscode_uri_1 = require("vscode-uri");
|
|
10
15
|
const data_1 = require("../data");
|
|
16
|
+
const htmlFormatter_1 = require("../htmlFormatter");
|
|
11
17
|
const nameCasing_1 = require("../nameCasing");
|
|
12
18
|
const utils_1 = require("../utils");
|
|
13
19
|
const specialTags = new Set([
|
|
@@ -23,11 +29,19 @@ const specialProps = new Set([
|
|
|
23
29
|
'ref',
|
|
24
30
|
'style',
|
|
25
31
|
]);
|
|
32
|
+
const builtInComponents = new Set([
|
|
33
|
+
'Transition',
|
|
34
|
+
'TransitionGroup',
|
|
35
|
+
'KeepAlive',
|
|
36
|
+
'Suspense',
|
|
37
|
+
'Teleport',
|
|
38
|
+
]);
|
|
26
39
|
let builtInData;
|
|
27
40
|
let modelData;
|
|
28
|
-
function create(languageId, { getComponentNames, getComponentProps, getComponentEvents, getComponentDirectives, getComponentSlots, getElementAttrs, resolveModuleName, }) {
|
|
41
|
+
function create(ts, languageId, { getComponentNames, getComponentProps, getComponentEvents, getComponentDirectives, getComponentSlots, getElementAttrs, resolveModuleName, getAutoImportSuggestions, resolveAutoImportCompletionEntry, }) {
|
|
29
42
|
let customData = [];
|
|
30
43
|
let extraCustomData = [];
|
|
44
|
+
let modulePathCache;
|
|
31
45
|
const onDidChangeCustomDataListeners = new Set();
|
|
32
46
|
const onDidChangeCustomData = (listener) => {
|
|
33
47
|
onDidChangeCustomDataListeners.add(listener);
|
|
@@ -53,7 +67,35 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
|
|
|
53
67
|
useDefaultDataProvider: false,
|
|
54
68
|
getDocumentContext(context) {
|
|
55
69
|
return {
|
|
56
|
-
resolveReference
|
|
70
|
+
resolveReference(ref, base) {
|
|
71
|
+
let baseUri = vscode_uri_1.URI.parse(base);
|
|
72
|
+
const decoded = context.decodeEmbeddedDocumentUri(baseUri);
|
|
73
|
+
if (decoded) {
|
|
74
|
+
baseUri = decoded[0];
|
|
75
|
+
}
|
|
76
|
+
if (modulePathCache
|
|
77
|
+
&& baseUri.scheme === 'file'
|
|
78
|
+
&& !ref.startsWith('./')
|
|
79
|
+
&& !ref.startsWith('../')) {
|
|
80
|
+
const map = modulePathCache;
|
|
81
|
+
if (!map.has(ref)) {
|
|
82
|
+
const fileName = baseUri.fsPath.replace(/\\/g, '/');
|
|
83
|
+
const promise = resolveModuleName(fileName, ref);
|
|
84
|
+
map.set(ref, promise);
|
|
85
|
+
if (promise instanceof Promise) {
|
|
86
|
+
promise.then(res => map.set(ref, res));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const cached = modulePathCache.get(ref);
|
|
90
|
+
if (cached instanceof Promise) {
|
|
91
|
+
throw cached;
|
|
92
|
+
}
|
|
93
|
+
if (cached) {
|
|
94
|
+
return cached;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return (0, volar_service_html_1.resolveReference)(ref, baseUri, context.env.workspaceFolders);
|
|
98
|
+
},
|
|
57
99
|
};
|
|
58
100
|
},
|
|
59
101
|
getCustomData() {
|
|
@@ -101,6 +143,43 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
|
|
|
101
143
|
}
|
|
102
144
|
return parseHTMLDocument(document);
|
|
103
145
|
};
|
|
146
|
+
htmlService.format = (document, range, options) => {
|
|
147
|
+
let voidElements;
|
|
148
|
+
const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
|
|
149
|
+
const codegen = info && language_core_1.tsCodegen.get(info.root.sfc);
|
|
150
|
+
if (codegen) {
|
|
151
|
+
const componentNames = new Set([
|
|
152
|
+
...codegen.getImportComponentNames(),
|
|
153
|
+
...codegen.getSetupExposed(),
|
|
154
|
+
]);
|
|
155
|
+
// copied from https://github.com/microsoft/vscode-html-languageservice/blob/10daf45dc16b4f4228987cf7cddf3a7dbbdc7570/src/beautify/beautify-html.js#L2746-L2761
|
|
156
|
+
voidElements = [
|
|
157
|
+
'area',
|
|
158
|
+
'base',
|
|
159
|
+
'br',
|
|
160
|
+
'col',
|
|
161
|
+
'embed',
|
|
162
|
+
'hr',
|
|
163
|
+
'img',
|
|
164
|
+
'input',
|
|
165
|
+
'keygen',
|
|
166
|
+
'link',
|
|
167
|
+
'menuitem',
|
|
168
|
+
'meta',
|
|
169
|
+
'param',
|
|
170
|
+
'source',
|
|
171
|
+
'track',
|
|
172
|
+
'wbr',
|
|
173
|
+
'!doctype',
|
|
174
|
+
'?xml',
|
|
175
|
+
'basefont',
|
|
176
|
+
'isindex',
|
|
177
|
+
].filter(tag => tag
|
|
178
|
+
&& !componentNames.has(tag)
|
|
179
|
+
&& !componentNames.has((0, shared_1.capitalize)((0, shared_1.camelize)(tag))));
|
|
180
|
+
}
|
|
181
|
+
return (0, htmlFormatter_1.format)(document, range, options, voidElements);
|
|
182
|
+
};
|
|
104
183
|
}
|
|
105
184
|
builtInData ??= (0, data_1.loadTemplateData)(context.env.locale ?? 'en');
|
|
106
185
|
modelData ??= (0, data_1.loadModelModifiersData)(context.env.locale ?? 'en');
|
|
@@ -148,13 +227,24 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
|
|
|
148
227
|
}
|
|
149
228
|
}
|
|
150
229
|
const disposable = context.env.onDidChangeConfiguration?.(() => initializing = undefined);
|
|
230
|
+
const transformedItems = new WeakSet();
|
|
151
231
|
let initializing;
|
|
232
|
+
let formattingOptions;
|
|
233
|
+
let lastCompletionDocument;
|
|
152
234
|
return {
|
|
153
235
|
...baseServiceInstance,
|
|
154
236
|
dispose() {
|
|
155
237
|
baseServiceInstance.dispose?.();
|
|
156
238
|
disposable?.dispose();
|
|
157
239
|
},
|
|
240
|
+
provideDocumentFormattingEdits(document, range, options, ...rest) {
|
|
241
|
+
formattingOptions = options;
|
|
242
|
+
return baseServiceInstance.provideDocumentFormattingEdits?.(document, range, options, ...rest);
|
|
243
|
+
},
|
|
244
|
+
provideOnTypeFormattingEdits(document, position, key, options, ...rest) {
|
|
245
|
+
formattingOptions = options;
|
|
246
|
+
return baseServiceInstance.provideOnTypeFormattingEdits?.(document, position, key, options, ...rest);
|
|
247
|
+
},
|
|
158
248
|
async provideCompletionItems(document, position, completionContext, token) {
|
|
159
249
|
if (document.languageId !== languageId) {
|
|
160
250
|
return;
|
|
@@ -163,23 +253,62 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
|
|
|
163
253
|
if (info?.code.id !== 'template') {
|
|
164
254
|
return;
|
|
165
255
|
}
|
|
166
|
-
const { result:
|
|
167
|
-
if (!
|
|
256
|
+
const { result: htmlCompletion, target, info: { tagNameCasing, components, propMap, }, } = await runWithVueData(info.script.id, info.root, () => baseServiceInstance.provideCompletionItems(document, position, completionContext, token));
|
|
257
|
+
if (!htmlCompletion) {
|
|
168
258
|
return;
|
|
169
259
|
}
|
|
260
|
+
const autoImportPlaceholderIndex = htmlCompletion.items.findIndex(item => item.label === 'AutoImportsPlaceholder');
|
|
261
|
+
if (autoImportPlaceholderIndex !== -1) {
|
|
262
|
+
const offset = document.offsetAt(position);
|
|
263
|
+
const map = context.language.maps.get(info.code, info.script);
|
|
264
|
+
let spliced = false;
|
|
265
|
+
for (const [sourceOffset] of map.toSourceLocation(offset)) {
|
|
266
|
+
const [formatOptions, preferences] = await Promise.all([
|
|
267
|
+
(0, getFormatCodeSettings_js_1.getFormatCodeSettings)(context, document, formattingOptions),
|
|
268
|
+
(0, getUserPreferences_js_1.getUserPreferences)(context, document),
|
|
269
|
+
]);
|
|
270
|
+
const autoImport = await getAutoImportSuggestions(info.root.fileName, sourceOffset, preferences, formatOptions);
|
|
271
|
+
if (!autoImport) {
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
const tsCompletion = (0, lspConverters_js_1.convertCompletionInfo)(ts, autoImport, document, position, entry => entry.data);
|
|
275
|
+
const placeholder = htmlCompletion.items[autoImportPlaceholderIndex];
|
|
276
|
+
for (const tsItem of tsCompletion.items) {
|
|
277
|
+
if (placeholder.textEdit) {
|
|
278
|
+
const newText = tsItem.textEdit?.newText ?? tsItem.label;
|
|
279
|
+
tsItem.textEdit = {
|
|
280
|
+
...placeholder.textEdit,
|
|
281
|
+
newText: tagNameCasing === 0 /* TagNameCasing.Kebab */
|
|
282
|
+
? (0, language_core_1.hyphenateTag)(newText)
|
|
283
|
+
: newText,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
tsItem.textEdit = undefined;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
htmlCompletion.items.splice(autoImportPlaceholderIndex, 1, ...tsCompletion.items);
|
|
291
|
+
spliced = true;
|
|
292
|
+
lastCompletionDocument = document;
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
if (!spliced) {
|
|
296
|
+
htmlCompletion.items.splice(autoImportPlaceholderIndex, 1);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
170
299
|
switch (target) {
|
|
171
300
|
case 'tag': {
|
|
172
|
-
|
|
301
|
+
htmlCompletion.items.forEach(transformTag);
|
|
173
302
|
break;
|
|
174
303
|
}
|
|
175
304
|
case 'attribute': {
|
|
176
|
-
addDirectiveModifiers(
|
|
177
|
-
|
|
305
|
+
addDirectiveModifiers(htmlCompletion, document);
|
|
306
|
+
htmlCompletion.items.forEach(transformAttribute);
|
|
178
307
|
break;
|
|
179
308
|
}
|
|
180
309
|
}
|
|
181
310
|
updateExtraCustomData([]);
|
|
182
|
-
return
|
|
311
|
+
return htmlCompletion;
|
|
183
312
|
function transformTag(item) {
|
|
184
313
|
const tagName = (0, shared_1.capitalize)((0, shared_1.camelize)(item.label));
|
|
185
314
|
if (components?.includes(tagName)) {
|
|
@@ -277,6 +406,39 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
|
|
|
277
406
|
}
|
|
278
407
|
}
|
|
279
408
|
},
|
|
409
|
+
async resolveCompletionItem(item) {
|
|
410
|
+
if (item.data?.__isAutoImport || item.data?.__isComponentAutoImport) {
|
|
411
|
+
const embeddedUri = vscode_uri_1.URI.parse(lastCompletionDocument.uri);
|
|
412
|
+
const decoded = context.decodeEmbeddedDocumentUri(embeddedUri);
|
|
413
|
+
if (!decoded) {
|
|
414
|
+
return item;
|
|
415
|
+
}
|
|
416
|
+
const sourceScript = context.language.scripts.get(decoded[0]);
|
|
417
|
+
if (!sourceScript) {
|
|
418
|
+
return item;
|
|
419
|
+
}
|
|
420
|
+
const [formatOptions, preferences] = await Promise.all([
|
|
421
|
+
(0, getFormatCodeSettings_js_1.getFormatCodeSettings)(context, lastCompletionDocument, formattingOptions),
|
|
422
|
+
(0, getUserPreferences_js_1.getUserPreferences)(context, lastCompletionDocument),
|
|
423
|
+
]);
|
|
424
|
+
const details = await resolveAutoImportCompletionEntry(item.data, preferences, formatOptions);
|
|
425
|
+
if (details) {
|
|
426
|
+
const virtualCode = sourceScript.generated.embeddedCodes.get(decoded[1]);
|
|
427
|
+
const sourceDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
|
|
428
|
+
const embeddedDocument = context.documents.get(embeddedUri, virtualCode.languageId, virtualCode.snapshot);
|
|
429
|
+
const map = context.language.maps.get(virtualCode, sourceScript);
|
|
430
|
+
item = (0, language_service_1.transformCompletionItem)(item, embeddedRange => (0, featureWorkers_1.getSourceRange)([sourceDocument, embeddedDocument, map], embeddedRange), embeddedDocument, context);
|
|
431
|
+
(0, lspConverters_js_1.applyCompletionEntryDetails)(ts, item, details, sourceDocument, fileName => vscode_uri_1.URI.file(fileName), () => undefined);
|
|
432
|
+
transformedItems.add(item);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
return item;
|
|
436
|
+
},
|
|
437
|
+
transformCompletionItem(item) {
|
|
438
|
+
if (transformedItems.has(item)) {
|
|
439
|
+
return item;
|
|
440
|
+
}
|
|
441
|
+
},
|
|
280
442
|
provideHover(document, position, token) {
|
|
281
443
|
if (document.languageId !== languageId) {
|
|
282
444
|
return;
|
|
@@ -293,20 +455,22 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
|
|
|
293
455
|
return baseServiceInstance.provideHover?.(document, position, token);
|
|
294
456
|
},
|
|
295
457
|
async provideDocumentLinks(document, token) {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
458
|
+
modulePathCache = new Map();
|
|
459
|
+
while (true) {
|
|
460
|
+
try {
|
|
461
|
+
const result = await baseServiceInstance.provideDocumentLinks?.(document, token);
|
|
462
|
+
modulePathCache = undefined;
|
|
463
|
+
return result;
|
|
464
|
+
}
|
|
465
|
+
catch (e) {
|
|
466
|
+
if (e instanceof Promise) {
|
|
467
|
+
await e;
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
throw e;
|
|
471
|
+
}
|
|
307
472
|
}
|
|
308
473
|
}
|
|
309
|
-
return documentLinks;
|
|
310
474
|
},
|
|
311
475
|
};
|
|
312
476
|
async function runWithVueData(sourceDocumentUri, root, fn) {
|
|
@@ -322,12 +486,13 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
|
|
|
322
486
|
}
|
|
323
487
|
async function provideHtmlData(sourceDocumentUri, root) {
|
|
324
488
|
await (initializing ??= initialize());
|
|
325
|
-
const
|
|
489
|
+
const tagNameCasing = await (0, nameCasing_1.getTagNameCasing)(context, sourceDocumentUri);
|
|
490
|
+
const attrNameCasing = await (0, nameCasing_1.getAttrNameCasing)(context, sourceDocumentUri);
|
|
326
491
|
for (const tag of builtInData.tags ?? []) {
|
|
327
492
|
if (specialTags.has(tag.name)) {
|
|
328
493
|
continue;
|
|
329
494
|
}
|
|
330
|
-
if (
|
|
495
|
+
if (tagNameCasing === 0 /* TagNameCasing.Kebab */) {
|
|
331
496
|
tag.name = (0, language_core_1.hyphenateTag)(tag.name);
|
|
332
497
|
}
|
|
333
498
|
else {
|
|
@@ -375,32 +540,32 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
|
|
|
375
540
|
components = [];
|
|
376
541
|
tasks.push((async () => {
|
|
377
542
|
components = (await getComponentNames(root.fileName) ?? [])
|
|
378
|
-
.filter(name => name
|
|
379
|
-
&& name !== 'TransitionGroup'
|
|
380
|
-
&& name !== 'KeepAlive'
|
|
381
|
-
&& name !== 'Suspense'
|
|
382
|
-
&& name !== 'Teleport');
|
|
543
|
+
.filter(name => !builtInComponents.has(name));
|
|
383
544
|
version++;
|
|
384
545
|
})());
|
|
385
546
|
}
|
|
386
|
-
const
|
|
547
|
+
const codegen = language_core_1.tsCodegen.get(root.sfc);
|
|
387
548
|
const names = new Set();
|
|
388
549
|
const tags = [];
|
|
389
550
|
for (const tag of components) {
|
|
390
|
-
if (
|
|
551
|
+
if (tagNameCasing === 0 /* TagNameCasing.Kebab */) {
|
|
391
552
|
names.add((0, language_core_1.hyphenateTag)(tag));
|
|
392
553
|
}
|
|
393
554
|
else {
|
|
394
555
|
names.add(tag);
|
|
395
556
|
}
|
|
396
557
|
}
|
|
397
|
-
|
|
398
|
-
const name
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
558
|
+
if (codegen) {
|
|
559
|
+
for (const name of [
|
|
560
|
+
...codegen.getImportComponentNames(),
|
|
561
|
+
...codegen.getSetupExposed(),
|
|
562
|
+
]) {
|
|
563
|
+
if (tagNameCasing === 0 /* TagNameCasing.Kebab */) {
|
|
564
|
+
names.add((0, language_core_1.hyphenateTag)(name));
|
|
565
|
+
}
|
|
566
|
+
else {
|
|
567
|
+
names.add(name);
|
|
568
|
+
}
|
|
404
569
|
}
|
|
405
570
|
}
|
|
406
571
|
for (const name of names) {
|
|
@@ -450,10 +615,10 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
|
|
|
450
615
|
...attrs.map(attr => ({ name: attr })),
|
|
451
616
|
]) {
|
|
452
617
|
const isGlobal = prop.isAttribute || !propNameSet.has(prop.name);
|
|
453
|
-
const propName =
|
|
618
|
+
const propName = attrNameCasing === 1 /* AttrNameCasing.Camel */ ? prop.name : (0, language_core_1.hyphenateAttr)(prop.name);
|
|
454
619
|
const isEvent = (0, language_core_1.hyphenateAttr)(propName).startsWith('on-');
|
|
455
620
|
if (isEvent) {
|
|
456
|
-
const eventName =
|
|
621
|
+
const eventName = attrNameCasing === 1 /* AttrNameCasing.Camel */
|
|
457
622
|
? propName['on'.length].toLowerCase() + propName.slice('onX'.length)
|
|
458
623
|
: propName.slice('on-'.length);
|
|
459
624
|
for (const name of [
|
|
@@ -471,7 +636,7 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
|
|
|
471
636
|
}
|
|
472
637
|
else {
|
|
473
638
|
const propInfo = propInfos.find(prop => {
|
|
474
|
-
const name =
|
|
639
|
+
const name = attrNameCasing === 1 /* AttrNameCasing.Camel */ ? prop.name : (0, language_core_1.hyphenateAttr)(prop.name);
|
|
475
640
|
return name === propName;
|
|
476
641
|
});
|
|
477
642
|
for (const name of [
|
|
@@ -493,7 +658,7 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
|
|
|
493
658
|
}
|
|
494
659
|
}
|
|
495
660
|
for (const event of events) {
|
|
496
|
-
const eventName =
|
|
661
|
+
const eventName = attrNameCasing === 1 /* AttrNameCasing.Camel */ ? event : (0, language_core_1.hyphenateAttr)(event);
|
|
497
662
|
for (const name of [
|
|
498
663
|
'v-on:' + eventName,
|
|
499
664
|
'@' + eventName,
|
|
@@ -526,7 +691,7 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
|
|
|
526
691
|
}
|
|
527
692
|
}
|
|
528
693
|
for (const model of models) {
|
|
529
|
-
const name =
|
|
694
|
+
const name = attrNameCasing === 1 /* AttrNameCasing.Camel */ ? model : (0, language_core_1.hyphenateAttr)(model);
|
|
530
695
|
attributes.push({ name: 'v-model:' + name });
|
|
531
696
|
propMap.set('v-model:' + name, {
|
|
532
697
|
name,
|
|
@@ -556,6 +721,19 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
|
|
|
556
721
|
}));
|
|
557
722
|
},
|
|
558
723
|
},
|
|
724
|
+
{
|
|
725
|
+
getId: () => 'vue-auto-imports',
|
|
726
|
+
isApplicable: () => true,
|
|
727
|
+
provideTags() {
|
|
728
|
+
return [{ name: 'AutoImportsPlaceholder', attributes: [] }];
|
|
729
|
+
},
|
|
730
|
+
provideAttributes() {
|
|
731
|
+
return [];
|
|
732
|
+
},
|
|
733
|
+
provideValues() {
|
|
734
|
+
return [];
|
|
735
|
+
},
|
|
736
|
+
},
|
|
559
737
|
]);
|
|
560
738
|
return {
|
|
561
739
|
async sync() {
|
|
@@ -564,6 +742,7 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
|
|
|
564
742
|
version,
|
|
565
743
|
target,
|
|
566
744
|
info: {
|
|
745
|
+
tagNameCasing,
|
|
567
746
|
components,
|
|
568
747
|
propMap,
|
|
569
748
|
},
|
package/lib/utils.d.ts
CHANGED
|
@@ -6,4 +6,3 @@ export declare function resolveEmbeddedCode(context: LanguageServiceContext, uri
|
|
|
6
6
|
code: import("@volar/language-service").VirtualCode;
|
|
7
7
|
root: VueVirtualCode;
|
|
8
8
|
} | undefined;
|
|
9
|
-
export declare function createReferenceResolver(context: LanguageServiceContext, resolveReference: typeof import('volar-service-html').resolveReference, resolveModuleName: import('@vue/typescript-plugin/lib/requests').Requests['resolveModuleName']): (ref: string, base: string) => Promise<string>;
|
package/lib/utils.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.resolveEmbeddedCode = resolveEmbeddedCode;
|
|
4
|
-
exports.createReferenceResolver = createReferenceResolver;
|
|
5
4
|
const vscode_uri_1 = require("vscode-uri");
|
|
6
5
|
function resolveEmbeddedCode(context, uriStr) {
|
|
7
6
|
const uri = vscode_uri_1.URI.parse(uriStr);
|
|
@@ -17,18 +16,4 @@ function resolveEmbeddedCode(context, uriStr) {
|
|
|
17
16
|
root: sourceScript.generated.root,
|
|
18
17
|
};
|
|
19
18
|
}
|
|
20
|
-
function createReferenceResolver(context, resolveReference, resolveModuleName) {
|
|
21
|
-
return async (ref, base) => {
|
|
22
|
-
let uri = vscode_uri_1.URI.parse(base);
|
|
23
|
-
const decoded = context.decodeEmbeddedDocumentUri(uri);
|
|
24
|
-
if (decoded) {
|
|
25
|
-
uri = decoded[0];
|
|
26
|
-
}
|
|
27
|
-
let moduleName;
|
|
28
|
-
if (!ref.startsWith('./') && !ref.startsWith('../')) {
|
|
29
|
-
moduleName = await resolveModuleName(uri.fsPath, ref);
|
|
30
|
-
}
|
|
31
|
-
return moduleName ?? resolveReference(ref, uri, context.env.workspaceFolders);
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
19
|
//# sourceMappingURL=utils.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vue/language-service",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"data",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"update-html-data": "node ./scripts/update-html-data.js"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@volar/language-service": "2.4.
|
|
21
|
-
"@vue/language-core": "3.1.
|
|
20
|
+
"@volar/language-service": "2.4.26",
|
|
21
|
+
"@vue/language-core": "3.1.7",
|
|
22
22
|
"@vue/shared": "^3.5.0",
|
|
23
23
|
"path-browserify": "^1.0.1",
|
|
24
24
|
"volar-service-css": "0.0.67",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/node": "^22.10.4",
|
|
36
36
|
"@types/path-browserify": "^1.0.1",
|
|
37
|
-
"@volar/kit": "2.4.
|
|
38
|
-
"@volar/typescript": "2.4.
|
|
37
|
+
"@volar/kit": "2.4.26",
|
|
38
|
+
"@volar/typescript": "2.4.26",
|
|
39
39
|
"@vue/compiler-dom": "^3.5.0",
|
|
40
|
-
"@vue/typescript-plugin": "3.1.
|
|
40
|
+
"@vue/typescript-plugin": "3.1.7",
|
|
41
41
|
"vscode-css-languageservice": "^6.3.1"
|
|
42
42
|
},
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "20dcd47c0cb4ce30e2c5e3ef1986ce297c218a06"
|
|
44
44
|
}
|