@vue/language-service 1.9.0-alpha.3 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/template/en.json +2 -2
- package/data/template/fr.json +1 -1
- package/data/template/ja.json +2 -2
- package/data/template/ko.json +13 -13
- package/data/template/pt.json +18 -18
- package/data/template/zh-cn.json +2 -2
- package/index.d.ts +7 -0
- package/index.js +64 -0
- package/lib/ideFeatures/nameCasing.d.ts +13 -0
- package/{out → lib}/ideFeatures/nameCasing.js +82 -29
- package/lib/plugins/css.d.ts +2 -0
- package/lib/plugins/css.js +27 -0
- package/{out → lib}/plugins/data.d.ts +1 -2
- package/lib/plugins/vue-autoinsert-dotvalue.d.ts +10 -0
- package/{out → lib}/plugins/vue-autoinsert-dotvalue.js +70 -54
- package/lib/plugins/vue-autoinsert-parentheses.d.ts +2 -0
- package/lib/plugins/vue-autoinsert-parentheses.js +60 -0
- package/lib/plugins/vue-autoinsert-space.d.ts +2 -0
- package/lib/plugins/vue-autoinsert-space.js +34 -0
- package/lib/plugins/vue-codelens-references.d.ts +2 -0
- package/lib/plugins/vue-codelens-references.js +38 -0
- package/lib/plugins/vue-directive-comments.d.ts +2 -0
- package/lib/plugins/vue-directive-comments.js +61 -0
- package/lib/plugins/vue-document-drop.d.ts +2 -0
- package/lib/plugins/vue-document-drop.js +81 -0
- package/lib/plugins/vue-extract-file.d.ts +8 -0
- package/lib/plugins/vue-extract-file.js +258 -0
- package/lib/plugins/vue-sfc.d.ts +7 -0
- package/lib/plugins/vue-sfc.js +163 -0
- package/lib/plugins/vue-template.d.ts +3 -0
- package/lib/plugins/vue-template.js +594 -0
- package/lib/plugins/vue-toggle-v-bind-codeaction.d.ts +2 -0
- package/lib/plugins/vue-toggle-v-bind-codeaction.js +126 -0
- package/lib/plugins/vue-twoslash-queries.d.ts +2 -0
- package/lib/plugins/vue-twoslash-queries.js +50 -0
- package/lib/plugins/vue-visualize-hidden-callback-param.d.ts +2 -0
- package/lib/plugins/vue-visualize-hidden-callback-param.js +45 -0
- package/{out → lib}/types.d.ts +1 -2
- package/{out → lib}/types.js +1 -1
- package/package.json +20 -20
- package/scripts/update-html-data.js +426 -0
- package/out/helpers.d.ts +0 -17
- package/out/helpers.js +0 -235
- package/out/ideFeatures/dragImport.d.ts +0 -9
- package/out/ideFeatures/dragImport.js +0 -50
- package/out/ideFeatures/nameCasing.d.ts +0 -16
- package/out/index.d.ts +0 -8
- package/out/index.js +0 -26
- package/out/languageService.d.ts +0 -9
- package/out/languageService.js +0 -239
- package/out/plugins/vue-autoinsert-dotvalue.d.ts +0 -7
- package/out/plugins/vue-autoinsert-parentheses.d.ts +0 -3
- package/out/plugins/vue-autoinsert-parentheses.js +0 -61
- package/out/plugins/vue-autoinsert-space.d.ts +0 -3
- package/out/plugins/vue-autoinsert-space.js +0 -32
- package/out/plugins/vue-codelens-references.d.ts +0 -3
- package/out/plugins/vue-codelens-references.js +0 -54
- package/out/plugins/vue-directive-comments.d.ts +0 -3
- package/out/plugins/vue-directive-comments.js +0 -57
- package/out/plugins/vue-extract-file.d.ts +0 -9
- package/out/plugins/vue-extract-file.js +0 -293
- package/out/plugins/vue-template.d.ts +0 -12
- package/out/plugins/vue-template.js +0 -548
- package/out/plugins/vue-toggle-v-bind-codeaction.d.ts +0 -3
- package/out/plugins/vue-toggle-v-bind-codeaction.js +0 -126
- package/out/plugins/vue-twoslash-queries.d.ts +0 -3
- package/out/plugins/vue-twoslash-queries.js +0 -60
- package/out/plugins/vue-visualize-hidden-callback-param.d.ts +0 -3
- package/out/plugins/vue-visualize-hidden-callback-param.js +0 -43
- package/out/plugins/vue.d.ts +0 -8
- package/out/plugins/vue.js +0 -169
- /package/{out → lib}/plugins/data.js +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.create = void 0;
|
|
4
|
+
const volar_service_css_1 = require("volar-service-css");
|
|
5
|
+
function create() {
|
|
6
|
+
const base = (0, volar_service_css_1.create)({ scssDocumentSelector: ['scss', 'postcss'] });
|
|
7
|
+
return {
|
|
8
|
+
...base,
|
|
9
|
+
create(context) {
|
|
10
|
+
const baseInstance = base.create(context);
|
|
11
|
+
return {
|
|
12
|
+
...baseInstance,
|
|
13
|
+
async provideDiagnostics(document, token) {
|
|
14
|
+
let diagnostics = await baseInstance.provideDiagnostics?.(document, token) ?? [];
|
|
15
|
+
if (document.languageId === 'postcss') {
|
|
16
|
+
diagnostics = diagnostics.filter(diag => diag.code !== 'css-semicolonexpected');
|
|
17
|
+
diagnostics = diagnostics.filter(diag => diag.code !== 'css-ruleorselectorexpected');
|
|
18
|
+
diagnostics = diagnostics.filter(diag => diag.code !== 'unknownAtRules');
|
|
19
|
+
}
|
|
20
|
+
return diagnostics;
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
exports.create = create;
|
|
27
|
+
//# sourceMappingURL=css.js.map
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import * as html from 'vscode-html-languageservice';
|
|
1
|
+
import type * as html from 'vscode-html-languageservice';
|
|
2
2
|
export declare function loadTemplateData(lang: string): html.HTMLDataV1;
|
|
3
3
|
export declare function loadLanguageBlocks(lang: string): html.HTMLDataV1;
|
|
4
4
|
export declare function loadModelModifiersData(lang: string): html.HTMLDataV1;
|
|
5
|
-
//# sourceMappingURL=data.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ServicePlugin } from '@volar/language-service';
|
|
2
|
+
import type * as ts from 'typescript';
|
|
3
|
+
import type * as vscode from 'vscode-languageserver-protocol';
|
|
4
|
+
import type { TextDocument } from 'vscode-languageserver-textdocument';
|
|
5
|
+
export declare function create(ts: typeof import('typescript')): ServicePlugin;
|
|
6
|
+
export declare function isCharacterTyping(document: TextDocument, lastChange: {
|
|
7
|
+
range: vscode.Range;
|
|
8
|
+
text: string;
|
|
9
|
+
}): boolean;
|
|
10
|
+
export declare function isBlacklistNode(ts: typeof import('typescript'), node: ts.Node, pos: number, allowAccessDotValue: boolean): boolean;
|
|
@@ -2,62 +2,78 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.isBlacklistNode = exports.isCharacterTyping = exports.create = void 0;
|
|
4
4
|
const language_core_1 = require("@vue/language-core");
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
const namedPipeClient = require("@vue/typescript-plugin/lib/client");
|
|
6
|
+
const asts = new WeakMap();
|
|
7
|
+
function getAst(ts, fileName, snapshot, scriptKind) {
|
|
8
|
+
let ast = asts.get(snapshot);
|
|
9
|
+
if (!ast) {
|
|
10
|
+
ast = ts.createSourceFile(fileName, snapshot.getText(0, snapshot.getLength()), ts.ScriptTarget.Latest, undefined, scriptKind);
|
|
11
|
+
asts.set(snapshot, ast);
|
|
12
|
+
}
|
|
13
|
+
return ast;
|
|
14
|
+
}
|
|
15
|
+
function create(ts) {
|
|
9
16
|
return {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const type = checker.getTypeAtLocation(node);
|
|
38
|
-
const props = type.getProperties();
|
|
39
|
-
if (props.some(prop => prop.name === 'value')) {
|
|
40
|
-
return '${1:.value}';
|
|
41
|
-
}
|
|
42
|
-
function findPositionIdentifier(sourceFile, node, offset) {
|
|
43
|
-
let result;
|
|
44
|
-
node.forEachChild(child => {
|
|
45
|
-
if (!result) {
|
|
46
|
-
if (child.end === offset && ts.isIdentifier(child)) {
|
|
47
|
-
result = child;
|
|
17
|
+
name: 'vue-autoinsert-dotvalue',
|
|
18
|
+
create(context) {
|
|
19
|
+
let currentReq = 0;
|
|
20
|
+
return {
|
|
21
|
+
async provideAutoInsertionEdit(document, position, lastChange) {
|
|
22
|
+
if (!isTsDocument(document))
|
|
23
|
+
return;
|
|
24
|
+
if (!isCharacterTyping(document, lastChange))
|
|
25
|
+
return;
|
|
26
|
+
const req = ++currentReq;
|
|
27
|
+
// Wait for tsserver to sync
|
|
28
|
+
await sleep(250);
|
|
29
|
+
if (req !== currentReq)
|
|
30
|
+
return;
|
|
31
|
+
const enabled = await context.env.getConfiguration?.('vue.autoInsert.dotValue') ?? true;
|
|
32
|
+
if (!enabled)
|
|
33
|
+
return;
|
|
34
|
+
const [code, file] = context.documents.getVirtualCodeByUri(document.uri);
|
|
35
|
+
if (!file)
|
|
36
|
+
return;
|
|
37
|
+
let ast;
|
|
38
|
+
let sourceCodeOffset = document.offsetAt(position);
|
|
39
|
+
const fileName = context.env.typescript.uriToFileName(file.id);
|
|
40
|
+
if (file?.generated) {
|
|
41
|
+
const script = file.generated.languagePlugin.typescript?.getScript(file.generated.code);
|
|
42
|
+
if (script?.code !== code) {
|
|
43
|
+
return;
|
|
48
44
|
}
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
ast = getAst(ts, fileName, script.code.snapshot, script.scriptKind);
|
|
46
|
+
let mapped = false;
|
|
47
|
+
for (const [_1, [_2, map]] of context.language.files.getMaps(code)) {
|
|
48
|
+
const sourceOffset = map.getSourceOffset(document.offsetAt(position));
|
|
49
|
+
if (sourceOffset !== undefined) {
|
|
50
|
+
sourceCodeOffset = sourceOffset[0];
|
|
51
|
+
mapped = true;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (!mapped) {
|
|
56
|
+
return;
|
|
51
57
|
}
|
|
52
58
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
else {
|
|
60
|
+
ast = getAst(ts, fileName, file.snapshot);
|
|
61
|
+
}
|
|
62
|
+
if (isBlacklistNode(ts, ast, document.offsetAt(position), false))
|
|
63
|
+
return;
|
|
64
|
+
const props = await namedPipeClient.getPropertiesAtLocation(fileName, sourceCodeOffset) ?? [];
|
|
65
|
+
if (props.some(prop => prop === 'value')) {
|
|
66
|
+
return '${1:.value}';
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
};
|
|
56
70
|
},
|
|
57
71
|
};
|
|
58
|
-
}
|
|
59
|
-
const create = () => plugin;
|
|
72
|
+
}
|
|
60
73
|
exports.create = create;
|
|
74
|
+
function sleep(ms) {
|
|
75
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
76
|
+
}
|
|
61
77
|
function isTsDocument(document) {
|
|
62
78
|
return document.languageId === 'javascript' ||
|
|
63
79
|
document.languageId === 'typescript' ||
|
|
@@ -65,12 +81,12 @@ function isTsDocument(document) {
|
|
|
65
81
|
document.languageId === 'typescriptreact';
|
|
66
82
|
}
|
|
67
83
|
const charReg = /\w/;
|
|
68
|
-
function isCharacterTyping(document,
|
|
69
|
-
const lastCharacter =
|
|
70
|
-
const rangeStart =
|
|
84
|
+
function isCharacterTyping(document, lastChange) {
|
|
85
|
+
const lastCharacter = lastChange.text[lastChange.text.length - 1];
|
|
86
|
+
const rangeStart = lastChange.range.start;
|
|
71
87
|
const position = {
|
|
72
88
|
line: rangeStart.line,
|
|
73
|
-
character: rangeStart.character +
|
|
89
|
+
character: rangeStart.character + lastChange.text.length,
|
|
74
90
|
};
|
|
75
91
|
const nextCharacter = document.getText({
|
|
76
92
|
start: position,
|
|
@@ -79,7 +95,7 @@ function isCharacterTyping(document, options) {
|
|
|
79
95
|
if (lastCharacter === undefined) { // delete text
|
|
80
96
|
return false;
|
|
81
97
|
}
|
|
82
|
-
if (
|
|
98
|
+
if (lastChange.text.indexOf('\n') >= 0) { // multi-line change
|
|
83
99
|
return false;
|
|
84
100
|
}
|
|
85
101
|
return charReg.test(lastCharacter) && !charReg.test(nextCharacter);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.create = void 0;
|
|
4
|
+
const vue_autoinsert_dotvalue_1 = require("./vue-autoinsert-dotvalue");
|
|
5
|
+
function create(ts) {
|
|
6
|
+
return {
|
|
7
|
+
name: 'vue-autoinsert-parentheses',
|
|
8
|
+
create(context) {
|
|
9
|
+
return {
|
|
10
|
+
async provideAutoInsertionEdit(document, position, lastChange) {
|
|
11
|
+
const enabled = await context.env.getConfiguration?.('vue.autoInsert.parentheses') ?? false;
|
|
12
|
+
if (!enabled)
|
|
13
|
+
return;
|
|
14
|
+
if (!(0, vue_autoinsert_dotvalue_1.isCharacterTyping)(document, lastChange))
|
|
15
|
+
return;
|
|
16
|
+
const [virtualCode] = context.documents.getVirtualCodeByUri(document.uri);
|
|
17
|
+
if (virtualCode?.id !== 'template_format')
|
|
18
|
+
return;
|
|
19
|
+
const offset = document.offsetAt(position);
|
|
20
|
+
for (const mappedRange of virtualCode.mappings) {
|
|
21
|
+
const generatedCodeEnd = mappedRange.generatedOffsets[mappedRange.generatedOffsets.length - 1]
|
|
22
|
+
+ mappedRange.lengths[mappedRange.lengths.length - 1];
|
|
23
|
+
if (generatedCodeEnd === offset) {
|
|
24
|
+
const text = document.getText().substring(mappedRange.generatedOffsets[0], generatedCodeEnd);
|
|
25
|
+
const ast = ts.createSourceFile('', text, ts.ScriptTarget.Latest);
|
|
26
|
+
if (ast.statements.length === 1) {
|
|
27
|
+
const statement = ast.statements[0];
|
|
28
|
+
if (ts.isExpressionStatement(statement)
|
|
29
|
+
&& ((ts.isAsExpression(statement.expression)
|
|
30
|
+
&& ts.isTypeReferenceNode(statement.expression.type)
|
|
31
|
+
&& ts.isIdentifier(statement.expression.type.typeName)
|
|
32
|
+
&& statement.expression.type.typeName.text)
|
|
33
|
+
|| (ts.isBinaryExpression(statement.expression)
|
|
34
|
+
&& statement.expression.right.getText(ast)
|
|
35
|
+
&& statement.expression.operatorToken.kind === ts.SyntaxKind.InstanceOfKeyword)
|
|
36
|
+
|| (ts.isTypeOfExpression(statement.expression)
|
|
37
|
+
&& statement.expression.expression.getText(ast)))) {
|
|
38
|
+
// https://code.visualstudio.com/docs/editor/userdefinedsnippets#_grammar
|
|
39
|
+
const escapedText = text
|
|
40
|
+
.replaceAll('\\', '\\\\')
|
|
41
|
+
.replaceAll('$', '\\$')
|
|
42
|
+
.replaceAll('}', '\\}');
|
|
43
|
+
return {
|
|
44
|
+
range: {
|
|
45
|
+
start: document.positionAt(mappedRange.generatedOffsets[0]),
|
|
46
|
+
end: document.positionAt(generatedCodeEnd),
|
|
47
|
+
},
|
|
48
|
+
newText: '(' + escapedText + '$0' + ')',
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
exports.create = create;
|
|
60
|
+
//# sourceMappingURL=vue-autoinsert-parentheses.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.create = void 0;
|
|
4
|
+
function create() {
|
|
5
|
+
return {
|
|
6
|
+
name: 'vue-autoinsert-space',
|
|
7
|
+
create(context) {
|
|
8
|
+
return {
|
|
9
|
+
async provideAutoInsertionEdit(document, _, lastChange) {
|
|
10
|
+
if (document.languageId === 'html' || document.languageId === 'jade') {
|
|
11
|
+
const enabled = await context.env.getConfiguration?.('vue.autoInsert.bracketSpacing') ?? true;
|
|
12
|
+
if (!enabled)
|
|
13
|
+
return;
|
|
14
|
+
if (lastChange.text === '{}'
|
|
15
|
+
&& document.getText({
|
|
16
|
+
start: { line: lastChange.range.start.line, character: lastChange.range.start.character - 1 },
|
|
17
|
+
end: { line: lastChange.range.start.line, character: lastChange.range.start.character + 3 }
|
|
18
|
+
}) === '{{}}') {
|
|
19
|
+
return {
|
|
20
|
+
newText: ` $0 `,
|
|
21
|
+
range: {
|
|
22
|
+
start: { line: lastChange.range.start.line, character: lastChange.range.start.character + 1 },
|
|
23
|
+
end: { line: lastChange.range.start.line, character: lastChange.range.start.character + 1 }
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
exports.create = create;
|
|
34
|
+
//# sourceMappingURL=vue-autoinsert-space.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.create = void 0;
|
|
4
|
+
const language_core_1 = require("@vue/language-core");
|
|
5
|
+
function create() {
|
|
6
|
+
return {
|
|
7
|
+
name: 'vue-codelens-references',
|
|
8
|
+
create(context) {
|
|
9
|
+
return {
|
|
10
|
+
provideReferencesCodeLensRanges(document) {
|
|
11
|
+
return worker(document.uri, virtualCode => {
|
|
12
|
+
const result = [];
|
|
13
|
+
for (const map of context.documents.getMaps(virtualCode) ?? []) {
|
|
14
|
+
for (const mapping of map.map.mappings) {
|
|
15
|
+
if (!mapping.data.__referencesCodeLens)
|
|
16
|
+
continue;
|
|
17
|
+
result.push({
|
|
18
|
+
start: document.positionAt(mapping.generatedOffsets[0]),
|
|
19
|
+
end: document.positionAt(mapping.generatedOffsets[mapping.generatedOffsets.length - 1]
|
|
20
|
+
+ mapping.lengths[mapping.lengths.length - 1]),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
function worker(uri, callback) {
|
|
29
|
+
const [virtualCode, sourceFile] = context.documents.getVirtualCodeByUri(uri);
|
|
30
|
+
if (!(sourceFile?.generated?.code instanceof language_core_1.VueGeneratedCode) || !sourceFile)
|
|
31
|
+
return;
|
|
32
|
+
return callback(virtualCode, sourceFile);
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
exports.create = create;
|
|
38
|
+
//# sourceMappingURL=vue-codelens-references.js.map
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.create = void 0;
|
|
4
|
+
const cmds = [
|
|
5
|
+
'vue-ignore',
|
|
6
|
+
'vue-skip',
|
|
7
|
+
'vue-expect-error',
|
|
8
|
+
];
|
|
9
|
+
const directiveCommentReg = /<!--\s*@/;
|
|
10
|
+
function create() {
|
|
11
|
+
return {
|
|
12
|
+
name: 'vue-directive-comments',
|
|
13
|
+
triggerCharacters: ['@'],
|
|
14
|
+
create() {
|
|
15
|
+
return {
|
|
16
|
+
provideCompletionItems(document, position) {
|
|
17
|
+
if (document.languageId !== 'html')
|
|
18
|
+
return;
|
|
19
|
+
const line = document.getText({ start: { line: position.line, character: 0 }, end: position });
|
|
20
|
+
const cmdStart = line.match(directiveCommentReg);
|
|
21
|
+
if (!cmdStart)
|
|
22
|
+
return;
|
|
23
|
+
const startIndex = cmdStart.index + cmdStart[0].length;
|
|
24
|
+
const remainText = line.substring(startIndex);
|
|
25
|
+
const result = [];
|
|
26
|
+
for (const cmd of cmds) {
|
|
27
|
+
let match = true;
|
|
28
|
+
for (let i = 0; i < remainText.length; i++) {
|
|
29
|
+
if (remainText[i] !== cmd[i]) {
|
|
30
|
+
console.log(JSON.stringify(remainText[i]), JSON.stringify(cmd[i]));
|
|
31
|
+
match = false;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (match) {
|
|
36
|
+
result.push({
|
|
37
|
+
label: '@' + cmd,
|
|
38
|
+
textEdit: {
|
|
39
|
+
range: {
|
|
40
|
+
start: {
|
|
41
|
+
line: position.line,
|
|
42
|
+
character: startIndex - 1,
|
|
43
|
+
},
|
|
44
|
+
end: position,
|
|
45
|
+
},
|
|
46
|
+
newText: '@' + cmd,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
isIncomplete: false,
|
|
53
|
+
items: result,
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
exports.create = create;
|
|
61
|
+
//# sourceMappingURL=vue-directive-comments.js.map
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.create = void 0;
|
|
4
|
+
const language_core_1 = require("@vue/language-core");
|
|
5
|
+
const shared_1 = require("@vue/shared");
|
|
6
|
+
const path = require("path-browserify");
|
|
7
|
+
const vue_extract_file_1 = require("../plugins/vue-extract-file");
|
|
8
|
+
const types_1 = require("../types");
|
|
9
|
+
function create(ts) {
|
|
10
|
+
return {
|
|
11
|
+
name: 'vue-document-drop',
|
|
12
|
+
create(context) {
|
|
13
|
+
let casing = types_1.TagNameCasing.Pascal; // TODO
|
|
14
|
+
return {
|
|
15
|
+
async provideDocumentDropEdits(document, _position, dataTransfer) {
|
|
16
|
+
if (document.languageId !== 'html')
|
|
17
|
+
return;
|
|
18
|
+
const [virtualCode, sourceFile] = context.documents.getVirtualCodeByUri(document.uri);
|
|
19
|
+
const vueVirtualCode = sourceFile?.generated?.code;
|
|
20
|
+
if (!virtualCode || !(vueVirtualCode instanceof language_core_1.VueGeneratedCode))
|
|
21
|
+
return;
|
|
22
|
+
let importUri;
|
|
23
|
+
for (const [mimeType, item] of dataTransfer) {
|
|
24
|
+
if (mimeType === 'text/uri-list') {
|
|
25
|
+
importUri = item.value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (!importUri?.endsWith('.vue'))
|
|
29
|
+
return;
|
|
30
|
+
let baseName = importUri.substring(importUri.lastIndexOf('/') + 1);
|
|
31
|
+
baseName = baseName.substring(0, baseName.lastIndexOf('.'));
|
|
32
|
+
const newName = (0, shared_1.capitalize)((0, shared_1.camelize)(baseName));
|
|
33
|
+
const { sfc } = vueVirtualCode;
|
|
34
|
+
const script = sfc.scriptSetup ?? sfc.script;
|
|
35
|
+
if (!script)
|
|
36
|
+
return;
|
|
37
|
+
const additionalEdit = {};
|
|
38
|
+
const code = [...(0, language_core_1.forEachEmbeddedCode)(vueVirtualCode)].find(code => code.id === (sfc.scriptSetup ? 'scriptSetupFormat' : 'scriptFormat'));
|
|
39
|
+
const lastImportNode = (0, vue_extract_file_1.getLastImportNode)(ts, script.ast);
|
|
40
|
+
let importPath = path.relative(path.dirname(document.uri), importUri)
|
|
41
|
+
|| importUri.substring(importUri.lastIndexOf('/') + 1);
|
|
42
|
+
if (!importPath.startsWith('./') && !importPath.startsWith('../')) {
|
|
43
|
+
importPath = './' + importPath;
|
|
44
|
+
}
|
|
45
|
+
additionalEdit.changes ??= {};
|
|
46
|
+
additionalEdit.changes[context.documents.getVirtualCodeUri(sourceFile.id, code.id)] = [];
|
|
47
|
+
additionalEdit.changes[context.documents.getVirtualCodeUri(sourceFile.id, code.id)].push({
|
|
48
|
+
range: lastImportNode ? {
|
|
49
|
+
start: script.ast.getLineAndCharacterOfPosition(lastImportNode.end),
|
|
50
|
+
end: script.ast.getLineAndCharacterOfPosition(lastImportNode.end),
|
|
51
|
+
} : {
|
|
52
|
+
start: script.ast.getLineAndCharacterOfPosition(0),
|
|
53
|
+
end: script.ast.getLineAndCharacterOfPosition(0),
|
|
54
|
+
},
|
|
55
|
+
newText: `\nimport ${newName} from '${importPath}'`
|
|
56
|
+
+ (lastImportNode ? '' : '\n'),
|
|
57
|
+
});
|
|
58
|
+
if (sfc.script) {
|
|
59
|
+
const edit = (0, vue_extract_file_1.createAddComponentToOptionEdit)(ts, sfc.script.ast, newName);
|
|
60
|
+
if (edit) {
|
|
61
|
+
additionalEdit.changes[context.documents.getVirtualCodeUri(sourceFile.id, code.id)].push({
|
|
62
|
+
range: {
|
|
63
|
+
start: document.positionAt(edit.range.start),
|
|
64
|
+
end: document.positionAt(edit.range.end),
|
|
65
|
+
},
|
|
66
|
+
newText: edit.newText,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
insertText: `<${casing === types_1.TagNameCasing.Kebab ? (0, shared_1.hyphenate)(newName) : newName}$0 />`,
|
|
72
|
+
insertTextFormat: 2,
|
|
73
|
+
additionalEdit,
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
exports.create = create;
|
|
81
|
+
//# sourceMappingURL=vue-document-drop.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ServicePlugin } from '@volar/language-service';
|
|
2
|
+
import type * as ts from 'typescript';
|
|
3
|
+
export declare function create(ts: typeof import('typescript')): ServicePlugin;
|
|
4
|
+
export declare function getLastImportNode(ts: typeof import('typescript'), sourceFile: ts.SourceFile): ts.Node | undefined;
|
|
5
|
+
export declare function createAddComponentToOptionEdit(ts: typeof import('typescript'), ast: ts.SourceFile, componentName: string): {
|
|
6
|
+
range: import("@vue/language-core").TextRange;
|
|
7
|
+
newText: string;
|
|
8
|
+
} | undefined;
|