@vue/language-service 3.1.5 → 3.1.6

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 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,2 @@
1
+ import { type HTMLFormatConfiguration, Range, type TextDocument, type TextEdit } from 'vscode-html-languageservice';
2
+ export declare function format(document: TextDocument, range: Range | undefined, options: HTMLFormatConfiguration, voidElements?: string[]): TextEdit[];
@@ -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
@@ -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 checkCasing(context: LanguageServiceContext, uri: URI): Promise<{
12
- tag: TagNameCasing | undefined;
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.AttrNameCasing = exports.TagNameCasing = void 0;
4
- exports.checkCasing = checkCasing;
3
+ exports.getTagNameCasing = getTagNameCasing;
4
+ exports.getAttrNameCasing = getAttrNameCasing;
5
5
  const language_core_1 = require("@vue/language-core");
6
- var TagNameCasing;
7
- (function (TagNameCasing) {
8
- TagNameCasing[TagNameCasing["Kebab"] = 0] = "Kebab";
9
- TagNameCasing[TagNameCasing["Pascal"] = 1] = "Pascal";
10
- })(TagNameCasing || (exports.TagNameCasing = TagNameCasing = {}));
11
- var AttrNameCasing;
12
- (function (AttrNameCasing) {
13
- AttrNameCasing[AttrNameCasing["Kebab"] = 0] = "Kebab";
14
- AttrNameCasing[AttrNameCasing["Camel"] = 1] = "Camel";
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 (!(root instanceof language_core_1.VueVirtualCode)) {
41
- return { tag: [], attr: [] };
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 detectAttrCasing(code) {
49
- let tags;
50
- if (cache.has(code)) {
51
- tags = cache.get(code);
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
- else {
54
- cache.set(code, tags = collectTags(code));
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
- let tags;
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
- // TagName
87
- result.add(TagNameCasing.Pascal);
75
+ result.add(1 /* TagNameCasing.Pascal */);
88
76
  }
89
77
  else {
90
- // tag-name
91
- result.add(TagNameCasing.Kebab);
78
+ result.add(0 /* TagNameCasing.Kebab */);
92
79
  }
93
80
  }
94
81
  return [...result];
95
82
  }
96
- function collectTags(root) {
97
- if (!(root instanceof language_core_1.VueVirtualCode)) {
98
- return undefined;
99
- }
100
- const ast = root.sfc.template?.ast;
101
- if (!ast) {
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
  }
@@ -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: (0, utils_1.createReferenceResolver)(context, volar_service_css_1.resolveReference, resolveModuleName),
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 (isBlacklistNode(ts, ast, sourceOffset - startTagEnd, false)) {
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 isBlacklistNode(ts, node, pos, allowAccessDotValue) {
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 _isBlacklistNode = false;
107
+ let _shouldSkip = false;
108
108
  node.forEachChild(node => {
109
- if (_isBlacklistNode) {
109
+ if (_shouldSkip) {
110
110
  return;
111
111
  }
112
112
  if (pos >= node.getFullStart() && pos <= node.getEnd()) {
113
- if (isBlacklistNode(ts, node, pos, allowAccessDotValue)) {
114
- _isBlacklistNode = true;
113
+ if (shouldSkip(ts, node, pos, allowAccessDotValue)) {
114
+ _shouldSkip = true;
115
115
  }
116
116
  }
117
117
  });
118
- return _isBlacklistNode;
118
+ return _shouldSkip;
119
119
  }
120
- function isWatchOrUseFunction(fnName) {
121
- return fnName === 'watch'
122
- || fnName === 'unref'
123
- || fnName === 'triggerRef'
124
- || fnName === 'isRef'
125
- || (0, language_core_1.hyphenateAttr)(fnName).startsWith('use-');
126
- }
127
- function isTopLevelArgOrArrayTopLevelItemItem(node) {
128
- for (const arg of node.arguments) {
129
- if (pos >= arg.getFullStart() && pos <= arg.getEnd()) {
130
- if (ts.isIdentifier(arg)) {
131
- return true;
132
- }
133
- if (ts.isArrayLiteralExpression(arg)) {
134
- for (const el of arg.elements) {
135
- if (pos >= el.getFullStart() && pos <= el.getEnd()) {
136
- return ts.isIdentifier(el);
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 casing = await (0, nameCasing_1.checkCasing)(context, info.script.id);
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: `<${casing.tag === nameCasing_1.TagNameCasing.Kebab ? (0, shared_1.hyphenate)(newName) : newName}$0 />`,
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,2 @@
1
+ import type { LanguageServicePlugin } from '@volar/language-service';
2
+ export declare function create(): LanguageServicePlugin;
@@ -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 casing = await (0, nameCasing_1.checkCasing)(context, info.script.id);
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: ` :${casing.attr === nameCasing_1.AttrNameCasing.Kebab ? (0, language_core_1.hyphenateAttr)(requiredProp) : requiredProp}=`,
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 language_core_1 = require("@vue/language-core");
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
- const codegen = language_core_1.tsCodegen.get(sfc);
21
- const option = info.root.vueCompilerOptions.resolveStyleClassNames;
22
- const scopedClasses = codegen?.getGeneratedTemplate()?.scopedClasses ?? [];
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 (let i = 0; i < sfc.styles.length; i++) {
25
- const style = sfc.styles[i];
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, 'style_' + i);
30
- const styleVirtualCode = info.script.generated.embeddedCodes.get('style_' + i);
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(({ className, offset }) => {
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
- function create() {
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 { LanguageServicePlugin } from '@volar/language-service';
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: (0, utils_1.createReferenceResolver)(context, volar_service_html_1.resolveReference, resolveModuleName),
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: completionList, target, info: { components, propMap, }, } = await runWithVueData(info.script.id, info.root, () => baseServiceInstance.provideCompletionItems(document, position, completionContext, token));
167
- if (!completionList) {
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
- completionList.items.forEach(transformTag);
301
+ htmlCompletion.items.forEach(transformTag);
173
302
  break;
174
303
  }
175
304
  case 'attribute': {
176
- addDirectiveModifiers(completionList, document);
177
- completionList.items.forEach(transformAttribute);
305
+ addDirectiveModifiers(htmlCompletion, document);
306
+ htmlCompletion.items.forEach(transformAttribute);
178
307
  break;
179
308
  }
180
309
  }
181
310
  updateExtraCustomData([]);
182
- return completionList;
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
- if (document.languageId !== languageId) {
297
- return;
298
- }
299
- const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
300
- if (info?.code.id !== 'template') {
301
- return;
302
- }
303
- const documentLinks = await baseServiceInstance.provideDocumentLinks?.(document, token) ?? [];
304
- for (const link of documentLinks) {
305
- if (link.target && (0, shared_1.isPromise)(link.target)) {
306
- link.target = await link.target;
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 casing = await (0, nameCasing_1.checkCasing)(context, sourceDocumentUri);
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 (casing.tag === nameCasing_1.TagNameCasing.Kebab) {
495
+ if (tagNameCasing === 0 /* TagNameCasing.Kebab */) {
331
496
  tag.name = (0, language_core_1.hyphenateTag)(tag.name);
332
497
  }
333
498
  else {
@@ -375,11 +540,7 @@ 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 !== 'Transition'
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
  }
@@ -387,7 +548,7 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
387
548
  const names = new Set();
388
549
  const tags = [];
389
550
  for (const tag of components) {
390
- if (casing.tag === nameCasing_1.TagNameCasing.Kebab) {
551
+ if (tagNameCasing === 0 /* TagNameCasing.Kebab */) {
391
552
  names.add((0, language_core_1.hyphenateTag)(tag));
392
553
  }
393
554
  else {
@@ -396,7 +557,7 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
396
557
  }
397
558
  for (const binding of scriptSetupRanges?.bindings ?? []) {
398
559
  const name = root.sfc.scriptSetup.content.slice(binding.range.start, binding.range.end);
399
- if (casing.tag === nameCasing_1.TagNameCasing.Kebab) {
560
+ if (tagNameCasing === 0 /* TagNameCasing.Kebab */) {
400
561
  names.add((0, language_core_1.hyphenateTag)(name));
401
562
  }
402
563
  else {
@@ -450,10 +611,10 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
450
611
  ...attrs.map(attr => ({ name: attr })),
451
612
  ]) {
452
613
  const isGlobal = prop.isAttribute || !propNameSet.has(prop.name);
453
- const propName = casing.attr === nameCasing_1.AttrNameCasing.Camel ? prop.name : (0, language_core_1.hyphenateAttr)(prop.name);
614
+ const propName = attrNameCasing === 1 /* AttrNameCasing.Camel */ ? prop.name : (0, language_core_1.hyphenateAttr)(prop.name);
454
615
  const isEvent = (0, language_core_1.hyphenateAttr)(propName).startsWith('on-');
455
616
  if (isEvent) {
456
- const eventName = casing.attr === nameCasing_1.AttrNameCasing.Camel
617
+ const eventName = attrNameCasing === 1 /* AttrNameCasing.Camel */
457
618
  ? propName['on'.length].toLowerCase() + propName.slice('onX'.length)
458
619
  : propName.slice('on-'.length);
459
620
  for (const name of [
@@ -471,7 +632,7 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
471
632
  }
472
633
  else {
473
634
  const propInfo = propInfos.find(prop => {
474
- const name = casing.attr === nameCasing_1.AttrNameCasing.Camel ? prop.name : (0, language_core_1.hyphenateAttr)(prop.name);
635
+ const name = attrNameCasing === 1 /* AttrNameCasing.Camel */ ? prop.name : (0, language_core_1.hyphenateAttr)(prop.name);
475
636
  return name === propName;
476
637
  });
477
638
  for (const name of [
@@ -493,7 +654,7 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
493
654
  }
494
655
  }
495
656
  for (const event of events) {
496
- const eventName = casing.attr === nameCasing_1.AttrNameCasing.Camel ? event : (0, language_core_1.hyphenateAttr)(event);
657
+ const eventName = attrNameCasing === 1 /* AttrNameCasing.Camel */ ? event : (0, language_core_1.hyphenateAttr)(event);
497
658
  for (const name of [
498
659
  'v-on:' + eventName,
499
660
  '@' + eventName,
@@ -526,7 +687,7 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
526
687
  }
527
688
  }
528
689
  for (const model of models) {
529
- const name = casing.attr === nameCasing_1.AttrNameCasing.Camel ? model : (0, language_core_1.hyphenateAttr)(model);
690
+ const name = attrNameCasing === 1 /* AttrNameCasing.Camel */ ? model : (0, language_core_1.hyphenateAttr)(model);
530
691
  attributes.push({ name: 'v-model:' + name });
531
692
  propMap.set('v-model:' + name, {
532
693
  name,
@@ -556,6 +717,19 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
556
717
  }));
557
718
  },
558
719
  },
720
+ {
721
+ getId: () => 'vue-auto-imports',
722
+ isApplicable: () => true,
723
+ provideTags() {
724
+ return [{ name: 'AutoImportsPlaceholder', attributes: [] }];
725
+ },
726
+ provideAttributes() {
727
+ return [];
728
+ },
729
+ provideValues() {
730
+ return [];
731
+ },
732
+ },
559
733
  ]);
560
734
  return {
561
735
  async sync() {
@@ -564,6 +738,7 @@ function create(languageId, { getComponentNames, getComponentProps, getComponent
564
738
  version,
565
739
  target,
566
740
  info: {
741
+ tagNameCasing,
567
742
  components,
568
743
  propMap,
569
744
  },
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.5",
3
+ "version": "3.1.6",
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.23",
21
- "@vue/language-core": "3.1.5",
20
+ "@volar/language-service": "2.4.26",
21
+ "@vue/language-core": "3.1.6",
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.23",
38
- "@volar/typescript": "2.4.23",
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.5",
40
+ "@vue/typescript-plugin": "3.1.6",
41
41
  "vscode-css-languageservice": "^6.3.1"
42
42
  },
43
- "gitHead": "d124a88fbf169e793c39ae4248da2092098de92d"
43
+ "gitHead": "341c06897f7f46606dddb8dd6d9e74e9c7844f02"
44
44
  }