@astrojs/language-server 0.13.3 → 0.15.0
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/CHANGELOG.md +34 -0
- package/dist/core/documents/utils.d.ts +6 -0
- package/dist/core/documents/utils.js +17 -1
- package/dist/plugins/PluginHost.d.ts +1 -1
- package/dist/plugins/PluginHost.js +29 -4
- package/dist/plugins/astro/AstroPlugin.d.ts +1 -1
- package/dist/plugins/astro/AstroPlugin.js +1 -1
- package/dist/plugins/astro/features/CompletionsProvider.d.ts +2 -2
- package/dist/plugins/astro/features/CompletionsProvider.js +24 -9
- package/dist/plugins/css/CSSPlugin.js +9 -1
- package/dist/plugins/css/features/astro-selectors.js +1 -2
- package/dist/plugins/html/features/astro-attributes.js +56 -1
- package/dist/plugins/html/utils.d.ts +1 -1
- package/dist/plugins/html/utils.js +1 -1
- package/dist/plugins/interfaces.d.ts +2 -2
- package/dist/plugins/typescript/TypeScriptPlugin.d.ts +6 -4
- package/dist/plugins/typescript/TypeScriptPlugin.js +12 -4
- package/dist/plugins/typescript/astro2tsx.d.ts +1 -1
- package/dist/plugins/typescript/astro2tsx.js +11 -6
- package/dist/plugins/typescript/features/CompletionsProvider.d.ts +23 -6
- package/dist/plugins/typescript/features/CompletionsProvider.js +256 -51
- package/dist/plugins/typescript/features/DiagnosticsProvider.js +44 -58
- package/dist/plugins/typescript/features/DocumentSymbolsProvider.js +8 -5
- package/dist/plugins/typescript/features/FoldingRangesProvider.d.ts +9 -0
- package/dist/plugins/typescript/features/FoldingRangesProvider.js +64 -0
- package/dist/plugins/typescript/features/SemanticTokenProvider.js +4 -1
- package/dist/plugins/typescript/features/utils.d.ts +2 -0
- package/dist/plugins/typescript/features/utils.js +7 -1
- package/dist/plugins/typescript/language-service.d.ts +1 -1
- package/dist/plugins/typescript/language-service.js +44 -23
- package/dist/plugins/typescript/snapshots/SnapshotManager.js +2 -1
- package/dist/plugins/typescript/snapshots/utils.js +24 -3
- package/dist/plugins/typescript/utils.d.ts +3 -0
- package/dist/plugins/typescript/utils.js +17 -1
- package/dist/server.js +16 -0
- package/dist/utils.d.ts +16 -0
- package/dist/utils.js +57 -1
- package/package.json +4 -4
- package/types/astro-jsx.d.ts +112 -113
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @astrojs/language-server
|
|
2
2
|
|
|
3
|
+
## 0.15.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 6bb45cb: Overhaul TypeScript completions
|
|
8
|
+
|
|
9
|
+
- Add support for completions inside expressions
|
|
10
|
+
- Add support for auto imports on completion
|
|
11
|
+
- Fix misc issues in completions (missing description, deprecated stuff not showing as deprecated)
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 7978de1: Add support for folding JavaScript
|
|
16
|
+
- 3ac74bc: Improve props completions on components
|
|
17
|
+
- Updated dependencies [6bb45cb]
|
|
18
|
+
- @astrojs/svelte-language-integration@0.1.3
|
|
19
|
+
|
|
20
|
+
## 0.14.0
|
|
21
|
+
|
|
22
|
+
### Minor Changes
|
|
23
|
+
|
|
24
|
+
- 9118c46: Add support for loading type definitions from Astro itself
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- 9ea5b97: Make TypeScript ignore content of Markdown tags
|
|
29
|
+
- dbf624a: Fix error when returning a response from the frontmatter
|
|
30
|
+
|
|
31
|
+
## 0.13.4
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- 5874655: Add support for Astro 0.26.0 attributes
|
|
36
|
+
|
|
3
37
|
## 0.13.3
|
|
4
38
|
|
|
5
39
|
### Patch Changes
|
|
@@ -11,9 +11,15 @@ export interface TagInformation {
|
|
|
11
11
|
start: number;
|
|
12
12
|
end: number;
|
|
13
13
|
};
|
|
14
|
+
closed: boolean;
|
|
14
15
|
}
|
|
15
16
|
export declare function walk(node: Node): Generator<Node, void, unknown>;
|
|
16
17
|
export declare function extractStyleTags(source: string, html?: HTMLDocument): TagInformation[];
|
|
18
|
+
export declare function getLineAtPosition(position: Position, text: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Returns the node if offset is inside a HTML start tag
|
|
21
|
+
*/
|
|
22
|
+
export declare function getNodeIfIsInHTMLStartTag(html: HTMLDocument, offset: number): Node | undefined;
|
|
17
23
|
/**
|
|
18
24
|
* Return if a Node is a Component
|
|
19
25
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getFirstNonWhitespaceIndex = exports.getLineOffsets = exports.offsetAt = exports.positionAt = exports.isInsideFrontmatter = exports.isInsideExpression = exports.isInTag = exports.isInComponentStartTag = exports.isComponentTag = exports.extractStyleTags = exports.walk = void 0;
|
|
3
|
+
exports.getFirstNonWhitespaceIndex = exports.getLineOffsets = exports.offsetAt = exports.positionAt = exports.isInsideFrontmatter = exports.isInsideExpression = exports.isInTag = exports.isInComponentStartTag = exports.isComponentTag = exports.getNodeIfIsInHTMLStartTag = exports.getLineAtPosition = exports.extractStyleTags = exports.walk = void 0;
|
|
4
4
|
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
5
5
|
const utils_1 = require("../../utils");
|
|
6
6
|
const parseHtml_1 = require("./parseHtml");
|
|
@@ -48,6 +48,8 @@ function extractTags(text, tag, html) {
|
|
|
48
48
|
startPos,
|
|
49
49
|
endPos,
|
|
50
50
|
container,
|
|
51
|
+
// vscode-html-languageservice types does not contain this, despite it existing. Annoying
|
|
52
|
+
closed: matchedNode.closed,
|
|
51
53
|
};
|
|
52
54
|
}
|
|
53
55
|
}
|
|
@@ -77,6 +79,20 @@ function parseAttributes(rawAttrs) {
|
|
|
77
79
|
return attrValue;
|
|
78
80
|
}
|
|
79
81
|
}
|
|
82
|
+
function getLineAtPosition(position, text) {
|
|
83
|
+
return text.substring(offsetAt({ line: position.line, character: 0 }, text), offsetAt({ line: position.line, character: Number.MAX_VALUE }, text));
|
|
84
|
+
}
|
|
85
|
+
exports.getLineAtPosition = getLineAtPosition;
|
|
86
|
+
/**
|
|
87
|
+
* Returns the node if offset is inside a HTML start tag
|
|
88
|
+
*/
|
|
89
|
+
function getNodeIfIsInHTMLStartTag(html, offset) {
|
|
90
|
+
const node = html.findNodeAt(offset);
|
|
91
|
+
if (!!node.tag && node.tag[0] === node.tag[0].toLowerCase() && (!node.startTagEnd || offset < node.startTagEnd)) {
|
|
92
|
+
return node;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.getNodeIfIsInHTMLStartTag = getNodeIfIsInHTMLStartTag;
|
|
80
96
|
/**
|
|
81
97
|
* Return if a Node is a Component
|
|
82
98
|
*/
|
|
@@ -12,7 +12,7 @@ export declare class PluginHost {
|
|
|
12
12
|
constructor(docManager: DocumentManager);
|
|
13
13
|
initialize(pluginHostConfig: PluginHostConfig): void;
|
|
14
14
|
registerPlugin(plugin: Plugin): void;
|
|
15
|
-
getCompletions(textDocument: TextDocumentIdentifier, position: Position, completionContext?: CompletionContext): Promise<CompletionList>;
|
|
15
|
+
getCompletions(textDocument: TextDocumentIdentifier, position: Position, completionContext?: CompletionContext, cancellationToken?: CancellationToken): Promise<CompletionList>;
|
|
16
16
|
resolveCompletion(textDocument: TextDocumentIdentifier, completionItem: AppCompletionItem): Promise<CompletionItem>;
|
|
17
17
|
getDiagnostics(textDocument: TextDocumentIdentifier): Promise<Diagnostic[]>;
|
|
18
18
|
doHover(textDocument: TextDocumentIdentifier, position: Position): Promise<Hover | null>;
|
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.PluginHost = void 0;
|
|
4
4
|
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
5
5
|
const lodash_1 = require("lodash");
|
|
6
|
+
const utils_1 = require("../utils");
|
|
7
|
+
const documents_1 = require("../core/documents");
|
|
6
8
|
var ExecuteMode;
|
|
7
9
|
(function (ExecuteMode) {
|
|
8
10
|
ExecuteMode[ExecuteMode["None"] = 0] = "None";
|
|
@@ -24,11 +26,34 @@ class PluginHost {
|
|
|
24
26
|
registerPlugin(plugin) {
|
|
25
27
|
this.plugins.push(plugin);
|
|
26
28
|
}
|
|
27
|
-
async getCompletions(textDocument, position, completionContext) {
|
|
29
|
+
async getCompletions(textDocument, position, completionContext, cancellationToken) {
|
|
28
30
|
const document = this.getDocument(textDocument.uri);
|
|
29
|
-
const completions =
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
const completions = await Promise.all(this.plugins.map(async (plugin) => {
|
|
32
|
+
const result = await this.tryExecutePlugin(plugin, 'getCompletions', [document, position, completionContext, cancellationToken], null);
|
|
33
|
+
if (result) {
|
|
34
|
+
return { result: result, plugin: plugin.__name };
|
|
35
|
+
}
|
|
36
|
+
})).then((fullCompletions) => fullCompletions.filter(utils_1.isNotNullOrUndefined));
|
|
37
|
+
const html = completions.find((completion) => completion.plugin === 'html');
|
|
38
|
+
const ts = completions.find((completion) => completion.plugin === 'typescript');
|
|
39
|
+
const astro = completions.find((completion) => completion.plugin === 'astro');
|
|
40
|
+
if (html && ts) {
|
|
41
|
+
if ((0, documents_1.getNodeIfIsInHTMLStartTag)(document.html, document.offsetAt(position))) {
|
|
42
|
+
ts.result.items = [];
|
|
43
|
+
}
|
|
44
|
+
// If the Astro plugin has completions for us, don't show TypeScript's as they're most likely duplicates
|
|
45
|
+
if (astro && astro.result.items.length > 0 && (0, documents_1.isInComponentStartTag)(document.html, document.offsetAt(position))) {
|
|
46
|
+
ts.result.items = [];
|
|
47
|
+
}
|
|
48
|
+
ts.result.items = ts.result.items.map((item) => {
|
|
49
|
+
if (item.sortText != '-1') {
|
|
50
|
+
item.sortText = 'Z' + (item.sortText || '');
|
|
51
|
+
}
|
|
52
|
+
return item;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
let flattenedCompletions = (0, lodash_1.flatten)(completions.map((completion) => completion.result.items));
|
|
56
|
+
const isIncomplete = completions.reduce((incomplete, completion) => incomplete || completion.result.isIncomplete, false);
|
|
32
57
|
return vscode_languageserver_1.CompletionList.create(flattenedCompletions, isIncomplete);
|
|
33
58
|
}
|
|
34
59
|
async resolveCompletion(textDocument, completionItem) {
|
|
@@ -9,7 +9,7 @@ export declare class AstroPlugin implements Plugin {
|
|
|
9
9
|
private readonly completionProvider;
|
|
10
10
|
constructor(docManager: DocumentManager, configManager: ConfigManager, workspaceUris: string[]);
|
|
11
11
|
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): Promise<AppCompletionList | null>;
|
|
12
|
-
getFoldingRanges(document: AstroDocument):
|
|
12
|
+
getFoldingRanges(document: AstroDocument): FoldingRange[];
|
|
13
13
|
getDefinitions(document: AstroDocument, position: Position): Promise<DefinitionLink[]>;
|
|
14
14
|
private isInsideFrontmatter;
|
|
15
15
|
private isComponentTag;
|
|
@@ -22,7 +22,7 @@ class AstroPlugin {
|
|
|
22
22
|
const completions = this.completionProvider.getCompletions(document, position, completionContext);
|
|
23
23
|
return completions;
|
|
24
24
|
}
|
|
25
|
-
|
|
25
|
+
getFoldingRanges(document) {
|
|
26
26
|
const foldingRanges = [];
|
|
27
27
|
const { frontmatter } = document.astroMeta;
|
|
28
28
|
// Currently editing frontmatter, don't fold
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { AppCompletionList } from '../../interfaces';
|
|
1
|
+
import type { AppCompletionList, CompletionsProvider } from '../../interfaces';
|
|
2
2
|
import type { AstroDocument, DocumentManager } from '../../../core/documents';
|
|
3
3
|
import { CompletionContext, Position } from 'vscode-languageserver';
|
|
4
4
|
import { LanguageServiceManager as TypeScriptLanguageServiceManager } from '../../typescript/LanguageServiceManager';
|
|
5
|
-
export declare class CompletionsProviderImpl {
|
|
5
|
+
export declare class CompletionsProviderImpl implements CompletionsProvider {
|
|
6
6
|
private readonly docManager;
|
|
7
7
|
private readonly languageServiceManager;
|
|
8
8
|
directivesHTMLLang: import("vscode-html-languageservice").LanguageService;
|
|
@@ -31,19 +31,18 @@ class CompletionsProviderImpl {
|
|
|
31
31
|
if (frontmatter)
|
|
32
32
|
items.push(frontmatter);
|
|
33
33
|
}
|
|
34
|
+
const html = document.html;
|
|
34
35
|
const offset = document.offsetAt(position);
|
|
35
|
-
|
|
36
|
+
const node = html.findNodeAt(offset);
|
|
37
|
+
if ((0, utils_1.isInComponentStartTag)(html, offset) && !(0, utils_1.isInsideExpression)(document.getText(), node.start, offset)) {
|
|
36
38
|
const props = await this.getPropCompletions(document, position, completionContext);
|
|
37
39
|
if (props.length) {
|
|
38
40
|
items.push(...props);
|
|
39
41
|
}
|
|
40
|
-
}
|
|
41
|
-
const html = document.html;
|
|
42
|
-
if ((0, utils_1.isInComponentStartTag)(html, offset)) {
|
|
43
|
-
const node = html.findNodeAt(offset);
|
|
44
42
|
const isAstro = await this.isAstroComponent(document, node);
|
|
45
43
|
if (!isAstro) {
|
|
46
|
-
|
|
44
|
+
const directives = (0, utils_4.removeDataAttrCompletion)(this.directivesHTMLLang.doComplete(document, position, html).items);
|
|
45
|
+
items.push(...directives);
|
|
47
46
|
}
|
|
48
47
|
}
|
|
49
48
|
return vscode_languageserver_1.CompletionList.create(items, true);
|
|
@@ -124,7 +123,8 @@ class CompletionsProviderImpl {
|
|
|
124
123
|
// Add completions for this component's props type properties
|
|
125
124
|
const properties = componentType.getProperties().filter((property) => property.name !== 'children') || [];
|
|
126
125
|
properties.forEach((property) => {
|
|
127
|
-
|
|
126
|
+
const type = typeChecker.getTypeOfSymbolAtLocation(property, imp);
|
|
127
|
+
let completionItem = this.getCompletionItemForProperty(property, typeChecker, type);
|
|
128
128
|
completionItems.push(completionItem);
|
|
129
129
|
});
|
|
130
130
|
// Ensure that props shows up first as a completion, despite this plugin being ran after the HTML one
|
|
@@ -181,10 +181,25 @@ class CompletionsProviderImpl {
|
|
|
181
181
|
}
|
|
182
182
|
return null;
|
|
183
183
|
}
|
|
184
|
-
getCompletionItemForProperty(mem, typeChecker) {
|
|
184
|
+
getCompletionItemForProperty(mem, typeChecker, type) {
|
|
185
|
+
const typeString = typeChecker.typeToString(type);
|
|
186
|
+
let insertText = mem.name;
|
|
187
|
+
switch (typeString) {
|
|
188
|
+
case 'string':
|
|
189
|
+
insertText = `${mem.name}="$1"`;
|
|
190
|
+
break;
|
|
191
|
+
case 'boolean':
|
|
192
|
+
insertText = mem.name;
|
|
193
|
+
break;
|
|
194
|
+
default:
|
|
195
|
+
insertText = `${mem.name}={$1}`;
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
185
198
|
let item = {
|
|
186
199
|
label: mem.name,
|
|
187
|
-
|
|
200
|
+
detail: typeString,
|
|
201
|
+
insertText: insertText,
|
|
202
|
+
insertTextFormat: vscode_languageserver_1.InsertTextFormat.Snippet,
|
|
188
203
|
commitCharacters: [],
|
|
189
204
|
};
|
|
190
205
|
mem.getDocumentationComment(typeChecker);
|
|
@@ -25,6 +25,12 @@ class CSSPlugin {
|
|
|
25
25
|
return null;
|
|
26
26
|
}
|
|
27
27
|
const styleTag = this.getStyleTagForPosition(document, position);
|
|
28
|
+
// We technically can return results even for open tags, however, a lot of the info returned is not valid
|
|
29
|
+
// Since most editors will automatically close the tag before the user start working in them, this shouldn't be a problem
|
|
30
|
+
if (styleTag && !styleTag.closed) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
// If we don't have a style tag at this position, we might be in a style property instead, let's check
|
|
28
34
|
if (!styleTag) {
|
|
29
35
|
const attributeContext = (0, parseHtml_1.getAttributeContextAtPosition)(document, position);
|
|
30
36
|
if (!attributeContext) {
|
|
@@ -61,7 +67,9 @@ class CSSPlugin {
|
|
|
61
67
|
return null;
|
|
62
68
|
}
|
|
63
69
|
const styleTag = this.getStyleTagForPosition(document, position);
|
|
64
|
-
|
|
70
|
+
if (styleTag && !styleTag.closed) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
65
73
|
if (!styleTag) {
|
|
66
74
|
const attributeContext = (0, parseHtml_1.getAttributeContextAtPosition)(document, position);
|
|
67
75
|
if (!attributeContext) {
|
|
@@ -4,8 +4,7 @@ exports.pseudoClass = void 0;
|
|
|
4
4
|
exports.pseudoClass = [
|
|
5
5
|
{
|
|
6
6
|
name: ':global()',
|
|
7
|
-
description:
|
|
8
|
-
Apply styles to a selector globally`,
|
|
7
|
+
description: 'Apply styles to a selector globally',
|
|
9
8
|
references: [
|
|
10
9
|
{
|
|
11
10
|
name: 'Astro documentation',
|
|
@@ -43,7 +43,7 @@ exports.astroAttributes = (0, vscode_html_languageservice_1.newHTMLDataProvider)
|
|
|
43
43
|
// The VS Code tag definitions does not provide a description for the deprecated `charset` attribute on script tags
|
|
44
44
|
// Which mean that since we get no hover info for this, we instead get JSX hover info. So we'll just specify a description ourselves for this specific case
|
|
45
45
|
name: 'charset',
|
|
46
|
-
description: "
|
|
46
|
+
description: "**Deprecated**\n\nIt's unnecessary to specify the charset attribute, because documents must use UTF-8, and the script element inherits its character encoding from the document.",
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
name: 'define:vars',
|
|
@@ -55,6 +55,28 @@ exports.astroAttributes = (0, vscode_html_languageservice_1.newHTMLDataProvider)
|
|
|
55
55
|
},
|
|
56
56
|
],
|
|
57
57
|
},
|
|
58
|
+
{
|
|
59
|
+
name: 'hoist',
|
|
60
|
+
description: '**Deprecated in Astro >= 0.26.0**\n\nBuilds, optimizes, and bundles your script with the other JavaScript on the page',
|
|
61
|
+
valueSet: 'v',
|
|
62
|
+
references: [
|
|
63
|
+
{
|
|
64
|
+
name: 'Astro documentation',
|
|
65
|
+
url: 'https://docs.astro.build/en/core-concepts/astro-components/#using-hoisted-scripts',
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'is:inline',
|
|
71
|
+
description: 'Leave a script tag inline in the page template. No processing will be done on its content',
|
|
72
|
+
valueSet: 'v',
|
|
73
|
+
references: [
|
|
74
|
+
{
|
|
75
|
+
name: 'Astro documentation',
|
|
76
|
+
url: 'https://docs.astro.build/en/migrate/#new-default-script-behavior',
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
},
|
|
58
80
|
],
|
|
59
81
|
},
|
|
60
82
|
{
|
|
@@ -70,6 +92,39 @@ exports.astroAttributes = (0, vscode_html_languageservice_1.newHTMLDataProvider)
|
|
|
70
92
|
},
|
|
71
93
|
],
|
|
72
94
|
},
|
|
95
|
+
{
|
|
96
|
+
name: 'global',
|
|
97
|
+
description: '**Deprecated in favor of `is:global` in >= Astro 0.26.0**\n\nOpts-out of automatic CSS scoping, all contents will be available globally',
|
|
98
|
+
valueSet: 'v',
|
|
99
|
+
references: [
|
|
100
|
+
{
|
|
101
|
+
name: 'Astro documentation',
|
|
102
|
+
url: 'https://docs.astro.build/en/guides/styling/#global-styles',
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: 'is:global',
|
|
108
|
+
description: 'Opts-out of automatic CSS scoping, all contents will be available globally',
|
|
109
|
+
valueSet: 'v',
|
|
110
|
+
references: [
|
|
111
|
+
{
|
|
112
|
+
name: 'Astro documentation',
|
|
113
|
+
url: 'https://docs.astro.build/en/guides/styling/#global-styles',
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: 'is:inline',
|
|
119
|
+
description: 'Leave a style tag inline in the page template. No processing will be done on its content',
|
|
120
|
+
valueSet: 'v',
|
|
121
|
+
references: [
|
|
122
|
+
{
|
|
123
|
+
name: 'Astro documentation',
|
|
124
|
+
url: 'https://docs.astro.build/en/migrate/#new-default-script-behavior',
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
},
|
|
73
128
|
],
|
|
74
129
|
},
|
|
75
130
|
],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CompletionItem } from 'vscode-languageserver-types';
|
|
2
2
|
/**
|
|
3
3
|
* The VS Code HTML language service provides a completion for data attributes that is independent from
|
|
4
|
-
* data providers, which mean that you can't disable it, so this function removes them from
|
|
4
|
+
* data providers, which mean that you can't disable it, so this function removes them from completions
|
|
5
5
|
*/
|
|
6
6
|
export declare function removeDataAttrCompletion(items: CompletionItem[]): CompletionItem[];
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.removeDataAttrCompletion = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* The VS Code HTML language service provides a completion for data attributes that is independent from
|
|
6
|
-
* data providers, which mean that you can't disable it, so this function removes them from
|
|
6
|
+
* data providers, which mean that you can't disable it, so this function removes them from completions
|
|
7
7
|
*/
|
|
8
8
|
function removeDataAttrCompletion(items) {
|
|
9
9
|
return items.filter((item) => !item.label.startsWith('data-'));
|
|
@@ -13,7 +13,7 @@ export interface DiagnosticsProvider {
|
|
|
13
13
|
export interface HoverProvider {
|
|
14
14
|
doHover(document: TextDocument, position: Position): Resolvable<Hover | null>;
|
|
15
15
|
}
|
|
16
|
-
export interface
|
|
16
|
+
export interface FoldingRangesProvider {
|
|
17
17
|
getFoldingRanges(document: TextDocument): Resolvable<FoldingRange[] | null>;
|
|
18
18
|
}
|
|
19
19
|
export interface CompletionsProvider<T extends TextDocumentIdentifier = any> {
|
|
@@ -81,7 +81,7 @@ export interface OnWatchFileChangesProvider {
|
|
|
81
81
|
export interface UpdateNonAstroFile {
|
|
82
82
|
updateNonAstroFile(fileName: string, changes: TextDocumentContentChangeEvent[]): void;
|
|
83
83
|
}
|
|
84
|
-
declare type ProviderBase = DiagnosticsProvider & HoverProvider & CompletionsProvider & DefinitionsProvider & FormattingProvider &
|
|
84
|
+
declare type ProviderBase = DiagnosticsProvider & HoverProvider & CompletionsProvider & DefinitionsProvider & FormattingProvider & FoldingRangesProvider & TagCompleteProvider & DocumentColorsProvider & ColorPresentationsProvider & DocumentSymbolsProvider & UpdateImportsProvider & CodeActionsProvider & FindReferencesProvider & RenameProvider & SignatureHelpProvider & SemanticTokensProvider & SelectionRangeProvider & OnWatchFileChangesProvider & LinkedEditingRangesProvider & UpdateNonAstroFile;
|
|
85
85
|
export declare type LSProvider = ProviderBase;
|
|
86
86
|
export declare type Plugin = Partial<ProviderBase> & {
|
|
87
87
|
__name: string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { CancellationToken, CompletionContext, DefinitionLink, Diagnostic, Hover, Position, Range, SemanticTokens, SignatureHelp, SignatureHelpContext, SymbolInformation, TextDocumentContentChangeEvent, WorkspaceEdit } from 'vscode-languageserver';
|
|
1
|
+
import { CancellationToken, CompletionContext, DefinitionLink, Diagnostic, FoldingRange, Hover, Position, Range, SemanticTokens, SignatureHelp, SignatureHelpContext, SymbolInformation, TextDocumentContentChangeEvent, WorkspaceEdit } from 'vscode-languageserver';
|
|
2
2
|
import { ConfigManager } from '../../core/config';
|
|
3
3
|
import { AstroDocument, DocumentManager } from '../../core/documents';
|
|
4
4
|
import { AppCompletionItem, AppCompletionList, OnWatchFileChangesParam, Plugin } from '../interfaces';
|
|
5
|
-
import {
|
|
5
|
+
import { CompletionItemData } from './features/CompletionsProvider';
|
|
6
6
|
export declare class TypeScriptPlugin implements Plugin {
|
|
7
7
|
__name: string;
|
|
8
8
|
private configManager;
|
|
@@ -13,13 +13,15 @@ export declare class TypeScriptPlugin implements Plugin {
|
|
|
13
13
|
private readonly diagnosticsProvider;
|
|
14
14
|
private readonly documentSymbolsProvider;
|
|
15
15
|
private readonly semanticTokensProvider;
|
|
16
|
+
private readonly foldingRangesProvider;
|
|
16
17
|
constructor(docManager: DocumentManager, configManager: ConfigManager, workspaceUris: string[]);
|
|
17
18
|
doHover(document: AstroDocument, position: Position): Promise<Hover | null>;
|
|
18
19
|
rename(document: AstroDocument, position: Position, newName: string): Promise<WorkspaceEdit | null>;
|
|
20
|
+
getFoldingRanges(document: AstroDocument): Promise<FoldingRange[] | null>;
|
|
19
21
|
getSemanticTokens(textDocument: AstroDocument, range?: Range, cancellationToken?: CancellationToken): Promise<SemanticTokens | null>;
|
|
20
22
|
getDocumentSymbols(document: AstroDocument): Promise<SymbolInformation[]>;
|
|
21
|
-
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): Promise<AppCompletionList<
|
|
22
|
-
resolveCompletion(document: AstroDocument, completionItem: AppCompletionItem<
|
|
23
|
+
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext, cancellationToken?: CancellationToken): Promise<AppCompletionList<CompletionItemData> | null>;
|
|
24
|
+
resolveCompletion(document: AstroDocument, completionItem: AppCompletionItem<CompletionItemData>, cancellationToken?: CancellationToken): Promise<AppCompletionItem<CompletionItemData>>;
|
|
23
25
|
getDefinitions(document: AstroDocument, position: Position): Promise<DefinitionLink[]>;
|
|
24
26
|
getDiagnostics(document: AstroDocument, cancellationToken?: CancellationToken): Promise<Diagnostic[]>;
|
|
25
27
|
onWatchFileChanges(onWatchFileChangesParas: OnWatchFileChangesParam[]): Promise<void>;
|
|
@@ -37,6 +37,7 @@ const LanguageServiceManager_1 = require("./LanguageServiceManager");
|
|
|
37
37
|
const utils_3 = require("./utils");
|
|
38
38
|
const DocumentSymbolsProvider_1 = require("./features/DocumentSymbolsProvider");
|
|
39
39
|
const SemanticTokenProvider_1 = require("./features/SemanticTokenProvider");
|
|
40
|
+
const FoldingRangesProvider_1 = require("./features/FoldingRangesProvider");
|
|
40
41
|
class TypeScriptPlugin {
|
|
41
42
|
constructor(docManager, configManager, workspaceUris) {
|
|
42
43
|
this.__name = 'typescript';
|
|
@@ -48,6 +49,7 @@ class TypeScriptPlugin {
|
|
|
48
49
|
this.diagnosticsProvider = new DiagnosticsProvider_1.DiagnosticsProviderImpl(this.languageServiceManager);
|
|
49
50
|
this.documentSymbolsProvider = new DocumentSymbolsProvider_1.DocumentSymbolsProviderImpl(this.languageServiceManager);
|
|
50
51
|
this.semanticTokensProvider = new SemanticTokenProvider_1.SemanticTokensProviderImpl(this.languageServiceManager);
|
|
52
|
+
this.foldingRangesProvider = new FoldingRangesProvider_1.FoldingRangesProviderImpl(this.languageServiceManager);
|
|
51
53
|
}
|
|
52
54
|
async doHover(document, position) {
|
|
53
55
|
if (!this.featureEnabled('hover')) {
|
|
@@ -78,7 +80,13 @@ class TypeScriptPlugin {
|
|
|
78
80
|
});
|
|
79
81
|
return edit;
|
|
80
82
|
}
|
|
83
|
+
async getFoldingRanges(document) {
|
|
84
|
+
return this.foldingRangesProvider.getFoldingRanges(document);
|
|
85
|
+
}
|
|
81
86
|
async getSemanticTokens(textDocument, range, cancellationToken) {
|
|
87
|
+
if (!this.featureEnabled('semanticTokens')) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
82
90
|
return this.semanticTokensProvider.getSemanticTokens(textDocument, range, cancellationToken);
|
|
83
91
|
}
|
|
84
92
|
async getDocumentSymbols(document) {
|
|
@@ -88,15 +96,15 @@ class TypeScriptPlugin {
|
|
|
88
96
|
const symbols = await this.documentSymbolsProvider.getDocumentSymbols(document);
|
|
89
97
|
return symbols;
|
|
90
98
|
}
|
|
91
|
-
async getCompletions(document, position, completionContext) {
|
|
99
|
+
async getCompletions(document, position, completionContext, cancellationToken) {
|
|
92
100
|
if (!this.featureEnabled('completions')) {
|
|
93
101
|
return null;
|
|
94
102
|
}
|
|
95
|
-
const completions = await this.completionProvider.getCompletions(document, position, completionContext);
|
|
103
|
+
const completions = await this.completionProvider.getCompletions(document, position, completionContext, cancellationToken);
|
|
96
104
|
return completions;
|
|
97
105
|
}
|
|
98
|
-
async resolveCompletion(document, completionItem) {
|
|
99
|
-
return this.completionProvider.resolveCompletion(document, completionItem);
|
|
106
|
+
async resolveCompletion(document, completionItem, cancellationToken) {
|
|
107
|
+
return this.completionProvider.resolveCompletion(document, completionItem, cancellationToken);
|
|
100
108
|
}
|
|
101
109
|
async getDefinitions(document, position) {
|
|
102
110
|
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const os_1 = require("os");
|
|
4
4
|
const parseAstro_1 = require("../../core/documents/parseAstro");
|
|
5
|
-
function addProps(content) {
|
|
5
|
+
function addProps(content, className) {
|
|
6
6
|
let defaultExportType = 'Record<string, any>';
|
|
7
7
|
if (/(interface|type) Props/.test(content)) {
|
|
8
8
|
defaultExportType = 'Props';
|
|
9
9
|
}
|
|
10
|
-
return os_1.EOL + `export default function (_props: ${defaultExportType}) {
|
|
10
|
+
return os_1.EOL + `export default function ${className}__AstroComponent_(_props: ${defaultExportType}): any {}`;
|
|
11
11
|
}
|
|
12
12
|
function escapeTemplateLiteralContent(content) {
|
|
13
13
|
return content.replace(/`/g, '\\`');
|
|
14
14
|
}
|
|
15
|
-
function default_1(content) {
|
|
15
|
+
function default_1(content, className) {
|
|
16
16
|
var _a, _b;
|
|
17
17
|
let result = {
|
|
18
18
|
code: '',
|
|
@@ -24,8 +24,9 @@ function default_1(content) {
|
|
|
24
24
|
frontMatterRaw = content
|
|
25
25
|
.substring((_a = astroDocument.frontmatter.startOffset) !== null && _a !== void 0 ? _a : 0, ((_b = astroDocument.frontmatter.endOffset) !== null && _b !== void 0 ? _b : 0) + 3)
|
|
26
26
|
// Handle case where semicolons is not used in the frontmatter section
|
|
27
|
+
// We need to add something before the semi-colon or TypeScript won't be able to do completions
|
|
27
28
|
.replace(/((?!^)(?<!;)\n)(---)/g, (_whole, start, _dashes) => {
|
|
28
|
-
return start + ';'
|
|
29
|
+
return start + '"";';
|
|
29
30
|
})
|
|
30
31
|
// Replace frontmatter marks with comments
|
|
31
32
|
.replace(/---/g, '///');
|
|
@@ -38,9 +39,13 @@ function default_1(content) {
|
|
|
38
39
|
.replace(/<\s*!--([^-->]*)(.*?)-->/gs, (whole) => {
|
|
39
40
|
return `{/*${whole}*/}`;
|
|
40
41
|
})
|
|
41
|
-
// Turn styles into internal strings
|
|
42
|
+
// Turn styles tags into internal strings
|
|
42
43
|
.replace(/<\s*style([^>]*)>(.*?)<\s*\/\s*style>/gs, (_whole, attrs, children) => {
|
|
43
44
|
return `<style${attrs}>{\`${escapeTemplateLiteralContent(children)}\`}</style>`;
|
|
45
|
+
})
|
|
46
|
+
// Turn Markdown tags into internal strings
|
|
47
|
+
.replace(/<\s*Markdown([^>]*)>(.*?)<\s*\/\s*Markdown>/gs, (_whole, attrs, children) => {
|
|
48
|
+
return `<Markdown${attrs}>{\`${escapeTemplateLiteralContent(children)}\`}</Markdown>`;
|
|
44
49
|
})
|
|
45
50
|
// Turn scripts into function calls
|
|
46
51
|
.replace(/<\s*script([^\/>]*)>(.*?)<\s*\/\s*script>/gs, (_whole, attrs, children, offset) => {
|
|
@@ -76,7 +81,7 @@ function default_1(content) {
|
|
|
76
81
|
htmlRaw +
|
|
77
82
|
os_1.EOL +
|
|
78
83
|
// Add TypeScript definitions
|
|
79
|
-
addProps(frontMatterRaw);
|
|
84
|
+
addProps(frontMatterRaw, className);
|
|
80
85
|
return result;
|
|
81
86
|
}
|
|
82
87
|
exports.default = default_1;
|
|
@@ -1,16 +1,33 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { CompletionContext, Position, TextDocumentIdentifier, TextEdit, CancellationToken } from 'vscode-languageserver';
|
|
2
2
|
import type { LanguageServiceManager } from '../LanguageServiceManager';
|
|
3
3
|
import { AstroDocument } from '../../../core/documents';
|
|
4
4
|
import ts from 'typescript';
|
|
5
5
|
import { AppCompletionItem, AppCompletionList, CompletionsProvider } from '../../interfaces';
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { AstroSnapshotFragment } from '../snapshots/DocumentSnapshot';
|
|
7
|
+
export interface CompletionItemData extends TextDocumentIdentifier {
|
|
8
|
+
filePath: string;
|
|
9
|
+
offset: number;
|
|
10
|
+
originalItem: ts.CompletionEntry;
|
|
8
11
|
}
|
|
9
|
-
export declare class CompletionsProviderImpl implements CompletionsProvider<
|
|
12
|
+
export declare class CompletionsProviderImpl implements CompletionsProvider<CompletionItemData> {
|
|
10
13
|
private languageServiceManager;
|
|
11
14
|
constructor(languageServiceManager: LanguageServiceManager);
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
private readonly validTriggerCharacters;
|
|
16
|
+
private isValidTriggerCharacter;
|
|
17
|
+
private lastCompletion?;
|
|
18
|
+
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext, cancellationToken?: CancellationToken): Promise<AppCompletionList<CompletionItemData> | null>;
|
|
19
|
+
resolveCompletion(document: AstroDocument, item: AppCompletionItem<CompletionItemData>, cancellationToken?: CancellationToken): Promise<AppCompletionItem<CompletionItemData>>;
|
|
14
20
|
private toCompletionItem;
|
|
21
|
+
private isValidCompletion;
|
|
22
|
+
codeActionChangeToTextEdit(document: AstroDocument, fragment: AstroSnapshotFragment, change: ts.TextChange): TextEdit;
|
|
15
23
|
private getCompletionDocument;
|
|
24
|
+
/**
|
|
25
|
+
* If the textEdit is out of the word range of the triggered position
|
|
26
|
+
* vscode would refuse to show the completions
|
|
27
|
+
* split those edits into additionalTextEdit to fix it
|
|
28
|
+
*/
|
|
29
|
+
private fixTextEditRange;
|
|
30
|
+
private canReuseLastCompletion;
|
|
31
|
+
private getExistingImports;
|
|
32
|
+
private isAstroComponentImport;
|
|
16
33
|
}
|