@astrojs/language-server 0.14.0 → 0.16.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/CHANGELOG.md +39 -0
- package/dist/check.js +1 -2
- package/dist/core/config/ConfigManager.d.ts +20 -16
- package/dist/core/config/ConfigManager.js +112 -46
- package/dist/core/config/interfaces.d.ts +0 -52
- package/dist/core/documents/DocumentMapper.js +2 -4
- package/dist/core/documents/parseAstro.js +1 -1
- package/dist/core/documents/utils.d.ts +5 -0
- package/dist/core/documents/utils.js +18 -5
- package/dist/plugins/PluginHost.d.ts +3 -2
- package/dist/plugins/PluginHost.js +37 -10
- package/dist/plugins/astro/AstroPlugin.d.ts +1 -6
- package/dist/plugins/astro/AstroPlugin.js +0 -82
- package/dist/plugins/astro/features/CompletionsProvider.js +30 -15
- package/dist/plugins/css/CSSPlugin.d.ts +5 -5
- package/dist/plugins/css/CSSPlugin.js +41 -20
- package/dist/plugins/html/HTMLPlugin.d.ts +4 -4
- package/dist/plugins/html/HTMLPlugin.js +20 -16
- package/dist/plugins/html/features/astro-attributes.js +44 -27
- package/dist/plugins/interfaces.d.ts +2 -2
- package/dist/plugins/typescript/LanguageServiceManager.js +1 -1
- package/dist/plugins/typescript/TypeScriptPlugin.d.ts +10 -7
- package/dist/plugins/typescript/TypeScriptPlugin.js +39 -112
- package/dist/plugins/typescript/astro-sys.js +3 -5
- package/dist/plugins/typescript/astro2tsx.d.ts +1 -1
- package/dist/plugins/typescript/astro2tsx.js +7 -7
- package/dist/plugins/typescript/features/CodeActionsProvider.d.ts +16 -0
- package/dist/plugins/typescript/features/CodeActionsProvider.js +147 -0
- package/dist/plugins/typescript/features/CompletionsProvider.d.ts +26 -7
- package/dist/plugins/typescript/features/CompletionsProvider.js +260 -56
- package/dist/plugins/typescript/features/DefinitionsProvider.d.ts +9 -0
- package/dist/plugins/typescript/features/DefinitionsProvider.js +36 -0
- package/dist/plugins/typescript/features/DiagnosticsProvider.js +2 -3
- package/dist/plugins/typescript/features/DocumentSymbolsProvider.js +5 -6
- 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 +2 -2
- package/dist/plugins/typescript/features/SignatureHelpProvider.js +2 -2
- package/dist/plugins/typescript/features/utils.d.ts +4 -0
- package/dist/plugins/typescript/features/utils.js +25 -3
- package/dist/plugins/typescript/language-service.js +5 -6
- package/dist/plugins/typescript/module-loader.js +1 -1
- package/dist/plugins/typescript/previewer.js +1 -1
- package/dist/plugins/typescript/snapshots/SnapshotManager.js +1 -1
- package/dist/plugins/typescript/snapshots/utils.js +27 -9
- package/dist/plugins/typescript/utils.d.ts +4 -0
- package/dist/plugins/typescript/utils.js +29 -1
- package/dist/server.js +43 -14
- package/dist/utils.d.ts +12 -0
- package/dist/utils.js +39 -3
- package/package.json +2 -2
|
@@ -132,7 +132,7 @@ async function createLanguageService(tsconfigPath, docContext, workspaceUris) {
|
|
|
132
132
|
function updateSnapshotFromDocument(document) {
|
|
133
133
|
const filePath = document.getFilePath() || '';
|
|
134
134
|
const prevSnapshot = snapshotManager.get(filePath);
|
|
135
|
-
if (
|
|
135
|
+
if (prevSnapshot?.version === document.version) {
|
|
136
136
|
return prevSnapshot;
|
|
137
137
|
}
|
|
138
138
|
if (!prevSnapshot) {
|
|
@@ -186,16 +186,15 @@ async function createLanguageService(tsconfigPath, docContext, workspaceUris) {
|
|
|
186
186
|
snapshotManager.updateNonAstroFile(fileName, changes);
|
|
187
187
|
}
|
|
188
188
|
function getParsedTSConfig() {
|
|
189
|
-
var _a, _b, _c, _d;
|
|
190
189
|
let configJson = (tsconfigPath && typescript_1.default.readConfigFile(tsconfigPath, typescript_1.default.sys.readFile).config) || {};
|
|
191
190
|
// If our user has types in their config but it doesn't include the types needed for Astro, add them to the config
|
|
192
|
-
if (
|
|
193
|
-
if (!
|
|
191
|
+
if (configJson.compilerOptions?.types) {
|
|
192
|
+
if (!configJson.compilerOptions?.types.includes('astro/env')) {
|
|
194
193
|
configJson.compilerOptions.types.push('astro/env');
|
|
195
194
|
}
|
|
196
195
|
if (astroVersion.major >= 1 &&
|
|
197
196
|
astroVersion.full !== '1.0.0-beta.0' &&
|
|
198
|
-
!
|
|
197
|
+
!configJson.compilerOptions?.types.includes('astro/astro-jsx')) {
|
|
199
198
|
configJson.compilerOptions.types.push('astro/astro-jsx');
|
|
200
199
|
}
|
|
201
200
|
}
|
|
@@ -203,7 +202,7 @@ async function createLanguageService(tsconfigPath, docContext, workspaceUris) {
|
|
|
203
202
|
// Delete include so that .astro files don't get mistakenly excluded by the user
|
|
204
203
|
delete configJson.include;
|
|
205
204
|
// If the user supplied exclude, let's use theirs otherwise, use ours
|
|
206
|
-
|
|
205
|
+
configJson.exclude ?? (configJson.exclude = getDefaultExclude());
|
|
207
206
|
// Everything here will always, unconditionally, be in the resulting config
|
|
208
207
|
const forcedCompilerOptions = {
|
|
209
208
|
noEmit: true,
|
|
@@ -39,7 +39,7 @@ class ModuleResolutionCache {
|
|
|
39
39
|
*/
|
|
40
40
|
delete(resolvedModuleName) {
|
|
41
41
|
this.cache.forEach((val, key) => {
|
|
42
|
-
if (
|
|
42
|
+
if (val?.resolvedFileName === resolvedModuleName) {
|
|
43
43
|
this.cache.delete(key);
|
|
44
44
|
}
|
|
45
45
|
});
|
|
@@ -72,7 +72,7 @@ function getTagBodyText(tag) {
|
|
|
72
72
|
function getTagDocumentation(tag) {
|
|
73
73
|
function getWithType() {
|
|
74
74
|
const body = (typescript_1.default.displayPartsToString(tag.text) || '').split(/^(\S+)\s*-?\s*/);
|
|
75
|
-
if (
|
|
75
|
+
if (body?.length === 3) {
|
|
76
76
|
const param = body[1];
|
|
77
77
|
const doc = body[2];
|
|
78
78
|
const label = `*@${tag.name}* \`${param}\``;
|
|
@@ -129,7 +129,7 @@ class SnapshotManager {
|
|
|
129
129
|
const { include, exclude } = this.fileSpec;
|
|
130
130
|
// Since we default to not include anything,
|
|
131
131
|
// just don't waste time on this
|
|
132
|
-
if (
|
|
132
|
+
if (include?.length === 0) {
|
|
133
133
|
return;
|
|
134
134
|
}
|
|
135
135
|
const projectFiles = typescript_1.default.sys
|
|
@@ -6,12 +6,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.createFromFrameworkFilePath = exports.createFromAstroFilePath = exports.createFromTSFilePath = exports.createFromNonAstroFilePath = exports.createFromFilePath = exports.createFromDocument = void 0;
|
|
7
7
|
const typescript_1 = __importDefault(require("typescript"));
|
|
8
8
|
const astro2tsx_1 = __importDefault(require("../astro2tsx"));
|
|
9
|
+
const vscode_uri_1 = require("vscode-uri");
|
|
9
10
|
const utils_1 = require("../utils");
|
|
10
11
|
const DocumentSnapshot_1 = require("./DocumentSnapshot");
|
|
11
12
|
const svelte_language_integration_1 = require("@astrojs/svelte-language-integration");
|
|
13
|
+
const utils_2 = require("../../../utils");
|
|
12
14
|
// Utilities to create Snapshots from different contexts
|
|
13
15
|
function createFromDocument(document) {
|
|
14
|
-
const { code } = (0, astro2tsx_1.default)(document.getText());
|
|
16
|
+
const { code } = (0, astro2tsx_1.default)(document.getText(), classNameFromFilename(document.getURL()));
|
|
15
17
|
return new DocumentSnapshot_1.AstroSnapshot(document, code, typescript_1.default.ScriptKind.TSX);
|
|
16
18
|
}
|
|
17
19
|
exports.createFromDocument = createFromDocument;
|
|
@@ -53,8 +55,7 @@ exports.createFromNonAstroFilePath = createFromNonAstroFilePath;
|
|
|
53
55
|
* @param options options that apply in case it's a svelte file
|
|
54
56
|
*/
|
|
55
57
|
function createFromTSFilePath(filePath) {
|
|
56
|
-
|
|
57
|
-
const originalText = (_a = typescript_1.default.sys.readFile(filePath)) !== null && _a !== void 0 ? _a : '';
|
|
58
|
+
const originalText = typescript_1.default.sys.readFile(filePath) ?? '';
|
|
58
59
|
return new DocumentSnapshot_1.TypeScriptDocumentSnapshot(0, filePath, originalText);
|
|
59
60
|
}
|
|
60
61
|
exports.createFromTSFilePath = createFromTSFilePath;
|
|
@@ -64,21 +65,38 @@ exports.createFromTSFilePath = createFromTSFilePath;
|
|
|
64
65
|
* @param createDocument function that is used to create a document
|
|
65
66
|
*/
|
|
66
67
|
function createFromAstroFilePath(filePath, createDocument) {
|
|
67
|
-
|
|
68
|
-
const originalText = (_a = typescript_1.default.sys.readFile(filePath)) !== null && _a !== void 0 ? _a : '';
|
|
68
|
+
const originalText = typescript_1.default.sys.readFile(filePath) ?? '';
|
|
69
69
|
return createFromDocument(createDocument(filePath, originalText));
|
|
70
70
|
}
|
|
71
71
|
exports.createFromAstroFilePath = createFromAstroFilePath;
|
|
72
72
|
function createFromFrameworkFilePath(filePath, framework) {
|
|
73
|
-
|
|
74
|
-
const originalText =
|
|
73
|
+
const className = classNameFromFilename(filePath);
|
|
74
|
+
const originalText = typescript_1.default.sys.readFile(filePath) ?? '';
|
|
75
75
|
let code = '';
|
|
76
76
|
if (framework === 'svelte') {
|
|
77
|
-
code = (0, svelte_language_integration_1.toTSX)(originalText);
|
|
77
|
+
code = (0, svelte_language_integration_1.toTSX)(originalText, className);
|
|
78
78
|
}
|
|
79
79
|
else {
|
|
80
|
-
code =
|
|
80
|
+
code = `export default function ${className}__AstroComponent_(props: Record<string, any>): any {}`;
|
|
81
81
|
}
|
|
82
82
|
return new DocumentSnapshot_1.TypeScriptDocumentSnapshot(0, filePath, code, typescript_1.default.ScriptKind.TSX);
|
|
83
83
|
}
|
|
84
84
|
exports.createFromFrameworkFilePath = createFromFrameworkFilePath;
|
|
85
|
+
function classNameFromFilename(filename) {
|
|
86
|
+
const url = vscode_uri_1.URI.parse(filename);
|
|
87
|
+
const withoutExtensions = vscode_uri_1.Utils.basename(url).slice(0, -vscode_uri_1.Utils.extname(url).length);
|
|
88
|
+
const withoutInvalidCharacters = withoutExtensions
|
|
89
|
+
.split('')
|
|
90
|
+
// Although "-" is invalid, we leave it in, pascal-case-handling will throw it out later
|
|
91
|
+
.filter((char) => /[A-Za-z$_\d-]/.test(char))
|
|
92
|
+
.join('');
|
|
93
|
+
const firstValidCharIdx = withoutInvalidCharacters
|
|
94
|
+
.split('')
|
|
95
|
+
// Although _ and $ are valid first characters for classes, they are invalid first characters
|
|
96
|
+
// for tag names. For a better import autocompletion experience, we therefore throw them out.
|
|
97
|
+
.findIndex((char) => /[A-Za-z]/.test(char));
|
|
98
|
+
const withoutLeadingInvalidCharacters = withoutInvalidCharacters.substr(firstValidCharIdx);
|
|
99
|
+
const inPascalCase = (0, utils_2.toPascalCase)(withoutLeadingInvalidCharacters);
|
|
100
|
+
const finalName = firstValidCharIdx === -1 ? `A${inPascalCase}` : inPascalCase;
|
|
101
|
+
return finalName;
|
|
102
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
import { CompletionItemKind, DiagnosticSeverity, Position, Range, SymbolKind, SemanticTokensLegend } from 'vscode-languageserver';
|
|
3
|
+
import { AstroDocument } from '../../core/documents';
|
|
3
4
|
import { SnapshotFragment } from './snapshots/DocumentSnapshot';
|
|
4
5
|
export declare const enum TokenType {
|
|
5
6
|
class = 0,
|
|
@@ -39,6 +40,9 @@ export declare function convertRange(document: {
|
|
|
39
40
|
length?: number;
|
|
40
41
|
}): Range;
|
|
41
42
|
export declare function convertToLocationRange(defDoc: SnapshotFragment, textSpan: ts.TextSpan): Range;
|
|
43
|
+
export declare function ensureFrontmatterInsert(resultRange: Range, document: AstroDocument): Range;
|
|
44
|
+
export declare function checkEndOfFileCodeInsert(resultRange: Range, document: AstroDocument): Range;
|
|
45
|
+
export declare function removeAstroComponentSuffix(name: string): string;
|
|
42
46
|
export declare type FrameworkExt = 'astro' | 'vue' | 'jsx' | 'tsx' | 'svelte';
|
|
43
47
|
declare type FrameworkVirtualExt = 'ts' | 'tsx';
|
|
44
48
|
export declare function getFrameworkFromFilePath(filePath: string): FrameworkExt;
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ensureRealFilePath = exports.ensureRealAstroFilePath = exports.toRealAstroFilePath = exports.toVirtualFilePath = exports.toVirtualAstroFilePath = exports.isVirtualFilePath = exports.isVirtualSvelteFilePath = exports.isVirtualVueFilePath = exports.isVirtualAstroFilePath = exports.isFrameworkFilePath = exports.isAstroFilePath = exports.isVirtualFrameworkFilePath = exports.getFrameworkFromFilePath = exports.convertToLocationRange = exports.convertRange = exports.mapSeverity = exports.getScriptKindFromFileName = exports.isSubPath = exports.findTsConfigPath = exports.getExtensionFromScriptKind = exports.getCommitCharactersForScriptElement = exports.scriptElementKindToCompletionItemKind = exports.symbolKindFromString = exports.getSemanticTokenLegend = void 0;
|
|
6
|
+
exports.ensureRealFilePath = exports.ensureRealAstroFilePath = exports.toRealAstroFilePath = exports.toVirtualFilePath = exports.toVirtualAstroFilePath = exports.isVirtualFilePath = exports.isVirtualSvelteFilePath = exports.isVirtualVueFilePath = exports.isVirtualAstroFilePath = exports.isFrameworkFilePath = exports.isAstroFilePath = exports.isVirtualFrameworkFilePath = exports.getFrameworkFromFilePath = exports.removeAstroComponentSuffix = exports.checkEndOfFileCodeInsert = exports.ensureFrontmatterInsert = exports.convertToLocationRange = exports.convertRange = exports.mapSeverity = exports.getScriptKindFromFileName = exports.isSubPath = exports.findTsConfigPath = exports.getExtensionFromScriptKind = exports.getCommitCharactersForScriptElement = exports.scriptElementKindToCompletionItemKind = exports.symbolKindFromString = exports.getSemanticTokenLegend = void 0;
|
|
7
7
|
const typescript_1 = __importDefault(require("typescript"));
|
|
8
8
|
const path_1 = require("path");
|
|
9
9
|
const utils_1 = require("../../utils");
|
|
@@ -239,6 +239,34 @@ function convertToLocationRange(defDoc, textSpan) {
|
|
|
239
239
|
return range;
|
|
240
240
|
}
|
|
241
241
|
exports.convertToLocationRange = convertToLocationRange;
|
|
242
|
+
// Some code actions will insert code at the start of the file instead of inside our frontmatter
|
|
243
|
+
// We'll redirect those to the proper starting place
|
|
244
|
+
function ensureFrontmatterInsert(resultRange, document) {
|
|
245
|
+
if (document.astroMeta.frontmatter.state === 'closed') {
|
|
246
|
+
const position = document.positionAt(document.astroMeta.frontmatter.startOffset);
|
|
247
|
+
position.line += 1;
|
|
248
|
+
position.character = resultRange.start.character;
|
|
249
|
+
return vscode_languageserver_1.Range.create(position, position);
|
|
250
|
+
}
|
|
251
|
+
return resultRange;
|
|
252
|
+
}
|
|
253
|
+
exports.ensureFrontmatterInsert = ensureFrontmatterInsert;
|
|
254
|
+
// Some code actions ill insert code at the end of the generated TSX file, so we'll manually
|
|
255
|
+
// redirect it to the end of the frontmatter instead
|
|
256
|
+
function checkEndOfFileCodeInsert(resultRange, document) {
|
|
257
|
+
if (resultRange.start.line > document.lineCount) {
|
|
258
|
+
if (document.astroMeta.frontmatter.state === 'closed') {
|
|
259
|
+
const position = document.positionAt(document.astroMeta.frontmatter.endOffset);
|
|
260
|
+
return vscode_languageserver_1.Range.create(position, position);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return resultRange;
|
|
264
|
+
}
|
|
265
|
+
exports.checkEndOfFileCodeInsert = checkEndOfFileCodeInsert;
|
|
266
|
+
function removeAstroComponentSuffix(name) {
|
|
267
|
+
return name.replace(/(\w+)__AstroComponent_/, '$1');
|
|
268
|
+
}
|
|
269
|
+
exports.removeAstroComponentSuffix = removeAstroComponentSuffix;
|
|
242
270
|
const VirtualExtension = {
|
|
243
271
|
ts: 'ts',
|
|
244
272
|
tsx: 'tsx',
|
package/dist/server.js
CHANGED
|
@@ -36,16 +36,17 @@ const PluginHost_1 = require("./plugins/PluginHost");
|
|
|
36
36
|
const plugins_1 = require("./plugins");
|
|
37
37
|
const utils_1 = require("./utils");
|
|
38
38
|
const utils_2 = require("./plugins/typescript/utils");
|
|
39
|
+
const CodeActionsProvider_1 = require("./plugins/typescript/features/CodeActionsProvider");
|
|
39
40
|
const TagCloseRequest = new vscode.RequestType('html/tag');
|
|
40
41
|
// Start the language server
|
|
41
42
|
function startLanguageServer(connection) {
|
|
42
43
|
// Create our managers
|
|
43
|
-
const configManager = new ConfigManager_1.ConfigManager();
|
|
44
44
|
const documentManager = new DocumentManager_1.DocumentManager();
|
|
45
45
|
const pluginHost = new PluginHost_1.PluginHost(documentManager);
|
|
46
|
+
const configManager = new ConfigManager_1.ConfigManager(connection);
|
|
47
|
+
let hasConfigurationCapability = false;
|
|
46
48
|
connection.onInitialize((params) => {
|
|
47
|
-
|
|
48
|
-
const workspaceUris = (_b = (_a = params.workspaceFolders) === null || _a === void 0 ? void 0 : _a.map((folder) => folder.uri.toString())) !== null && _b !== void 0 ? _b : [(_c = params.rootUri) !== null && _c !== void 0 ? _c : ''];
|
|
49
|
+
const workspaceUris = params.workspaceFolders?.map((folder) => folder.uri.toString()) ?? [params.rootUri ?? ''];
|
|
49
50
|
workspaceUris.forEach((uri) => {
|
|
50
51
|
uri = (0, utils_1.urlToPath)(uri);
|
|
51
52
|
const astroVersion = (0, utils_1.getUserAstroVersion)(uri);
|
|
@@ -62,9 +63,10 @@ function startLanguageServer(connection) {
|
|
|
62
63
|
});
|
|
63
64
|
}
|
|
64
65
|
});
|
|
66
|
+
hasConfigurationCapability = !!(params.capabilities.workspace && !!params.capabilities.workspace.configuration);
|
|
65
67
|
pluginHost.initialize({
|
|
66
|
-
filterIncompleteCompletions: !
|
|
67
|
-
definitionLinkSupport: !!
|
|
68
|
+
filterIncompleteCompletions: !params.initializationOptions?.dontFilterIncompleteCompletions,
|
|
69
|
+
definitionLinkSupport: !!params.capabilities.textDocument?.definition?.linkSupport,
|
|
68
70
|
});
|
|
69
71
|
// Register plugins
|
|
70
72
|
pluginHost.registerPlugin(new HTMLPlugin_1.HTMLPlugin(configManager));
|
|
@@ -74,15 +76,26 @@ function startLanguageServer(connection) {
|
|
|
74
76
|
pluginHost.registerPlugin(new AstroPlugin_1.AstroPlugin(documentManager, configManager, workspaceUris));
|
|
75
77
|
pluginHost.registerPlugin(new plugins_1.TypeScriptPlugin(documentManager, configManager, workspaceUris));
|
|
76
78
|
}
|
|
77
|
-
// Update language-server config with what the user supplied to us at launch
|
|
78
|
-
configManager.updateConfig(params.initializationOptions.configuration.astro);
|
|
79
|
-
configManager.updateEmmetConfig(params.initializationOptions.configuration.emmet);
|
|
80
79
|
return {
|
|
81
80
|
capabilities: {
|
|
82
|
-
textDocumentSync:
|
|
81
|
+
textDocumentSync: {
|
|
82
|
+
openClose: true,
|
|
83
|
+
change: vscode.TextDocumentSyncKind.Incremental,
|
|
84
|
+
save: {
|
|
85
|
+
includeText: true,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
83
88
|
foldingRangeProvider: true,
|
|
84
89
|
definitionProvider: true,
|
|
85
90
|
renameProvider: true,
|
|
91
|
+
codeActionProvider: {
|
|
92
|
+
codeActionKinds: [
|
|
93
|
+
vscode_languageserver_1.CodeActionKind.QuickFix,
|
|
94
|
+
vscode_languageserver_1.CodeActionKind.SourceOrganizeImports,
|
|
95
|
+
// VS Code specific
|
|
96
|
+
CodeActionsProvider_1.sortImportKind,
|
|
97
|
+
],
|
|
98
|
+
},
|
|
86
99
|
completionProvider: {
|
|
87
100
|
resolveProvider: true,
|
|
88
101
|
triggerCharacters: [
|
|
@@ -127,10 +140,18 @@ function startLanguageServer(connection) {
|
|
|
127
140
|
},
|
|
128
141
|
};
|
|
129
142
|
});
|
|
130
|
-
//
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
143
|
+
// The params don't matter here because in "pull mode" it's always null, it's intended that when the config is updated
|
|
144
|
+
// you should just reset "your internal cache" and get the config again for relevant documents, weird API design
|
|
145
|
+
connection.onDidChangeConfiguration(async (change) => {
|
|
146
|
+
if (hasConfigurationCapability) {
|
|
147
|
+
configManager.updateConfig();
|
|
148
|
+
documentManager.getAllOpenedByClient().forEach(async (document) => {
|
|
149
|
+
await configManager.getConfig('astro', document[1].uri);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
configManager.updateGlobalConfig(change.settings.astro || ConfigManager_1.defaultLSConfig);
|
|
154
|
+
}
|
|
134
155
|
});
|
|
135
156
|
// Documents
|
|
136
157
|
connection.onDidOpenTextDocument((params) => {
|
|
@@ -157,6 +178,7 @@ function startLanguageServer(connection) {
|
|
|
157
178
|
connection.onHover((params) => pluginHost.doHover(params.textDocument, params.position));
|
|
158
179
|
connection.onDefinition((evt) => pluginHost.getDefinitions(evt.textDocument, evt.position));
|
|
159
180
|
connection.onFoldingRanges((evt) => pluginHost.getFoldingRanges(evt.textDocument));
|
|
181
|
+
connection.onCodeAction((evt, cancellationToken) => pluginHost.getCodeActions(evt.textDocument, evt.range, evt.context, cancellationToken));
|
|
160
182
|
connection.onCompletion(async (evt) => {
|
|
161
183
|
const promise = pluginHost.getCompletions(evt.textDocument, evt.position, evt.context);
|
|
162
184
|
return promise;
|
|
@@ -185,10 +207,17 @@ function startLanguageServer(connection) {
|
|
|
185
207
|
updateAllDiagnostics();
|
|
186
208
|
});
|
|
187
209
|
documentManager.on('documentChange', (0, utils_1.debounceThrottle)(async (document) => diagnosticsManager.update(document), 1000));
|
|
188
|
-
documentManager.on('documentClose', (document) =>
|
|
210
|
+
documentManager.on('documentClose', (document) => {
|
|
211
|
+
diagnosticsManager.removeDiagnostics(document);
|
|
212
|
+
configManager.removeDocument(document.uri);
|
|
213
|
+
});
|
|
189
214
|
// Taking off 🚀
|
|
190
215
|
connection.onInitialized(() => {
|
|
191
216
|
connection.console.log('Successfully initialized! 🚀');
|
|
217
|
+
// Register for all configuration changes.
|
|
218
|
+
if (hasConfigurationCapability) {
|
|
219
|
+
connection.client.register(vscode_languageserver_1.DidChangeConfigurationNotification.type);
|
|
220
|
+
}
|
|
192
221
|
});
|
|
193
222
|
connection.listen();
|
|
194
223
|
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -16,6 +16,14 @@ export declare function pathToUrl(path: string): string;
|
|
|
16
16
|
* (bar or bar.astro in this example).
|
|
17
17
|
*/
|
|
18
18
|
export declare function getLastPartOfPath(path: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Transform a string into PascalCase
|
|
21
|
+
*/
|
|
22
|
+
export declare function toPascalCase(string: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Function to modify each line of a text, preserving the line break style (`\n` or `\r\n`)
|
|
25
|
+
*/
|
|
26
|
+
export declare function modifyLines(text: string, replacementFn: (line: string, lineIdx: number) => string): string;
|
|
19
27
|
/**
|
|
20
28
|
* Return true if a specific node could be a component.
|
|
21
29
|
* This is not a 100% sure test as it'll return false for any component that does not match the standard format for a component
|
|
@@ -28,6 +36,10 @@ export declare function clamp(num: number, min: number, max: number): number;
|
|
|
28
36
|
export declare function isNotNullOrUndefined<T>(val: T | undefined | null): val is T;
|
|
29
37
|
export declare function isInRange(range: Range, positionToTest: Position): boolean;
|
|
30
38
|
export declare function isBeforeOrEqualToPosition(position: Position, positionToTest: Position): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Get all matches of a regexp.
|
|
41
|
+
*/
|
|
42
|
+
export declare function getRegExpMatches(regex: RegExp, str: string): RegExpExecArray[];
|
|
31
43
|
/**
|
|
32
44
|
* Debounces a function but cancels previous invocation only if
|
|
33
45
|
* a second function determines it should.
|
package/dist/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getUserAstroVersion = exports.debounceThrottle = exports.debounceSameArg = exports.isBeforeOrEqualToPosition = exports.isInRange = exports.isNotNullOrUndefined = exports.clamp = exports.flatten = exports.isPossibleComponent = exports.getLastPartOfPath = exports.pathToUrl = exports.urlToPath = exports.normalizePath = exports.normalizeUri = void 0;
|
|
3
|
+
exports.getUserAstroVersion = exports.debounceThrottle = exports.debounceSameArg = exports.getRegExpMatches = exports.isBeforeOrEqualToPosition = exports.isInRange = exports.isNotNullOrUndefined = exports.clamp = exports.flatten = exports.isPossibleComponent = exports.modifyLines = exports.toPascalCase = exports.getLastPartOfPath = exports.pathToUrl = exports.urlToPath = exports.normalizePath = exports.normalizeUri = void 0;
|
|
4
4
|
const vscode_uri_1 = require("vscode-uri");
|
|
5
5
|
/** Normalizes a document URI */
|
|
6
6
|
function normalizeUri(uri) {
|
|
@@ -37,13 +37,37 @@ function getLastPartOfPath(path) {
|
|
|
37
37
|
return path.replace(/\\/g, '/').split('/').pop() || '';
|
|
38
38
|
}
|
|
39
39
|
exports.getLastPartOfPath = getLastPartOfPath;
|
|
40
|
+
/**
|
|
41
|
+
* Transform a string into PascalCase
|
|
42
|
+
*/
|
|
43
|
+
function toPascalCase(string) {
|
|
44
|
+
return `${string}`
|
|
45
|
+
.replace(new RegExp(/[-_]+/, 'g'), ' ')
|
|
46
|
+
.replace(new RegExp(/[^\w\s]/, 'g'), '')
|
|
47
|
+
.replace(new RegExp(/\s+(.)(\w*)/, 'g'), ($1, $2, $3) => `${$2.toUpperCase() + $3.toLowerCase()}`)
|
|
48
|
+
.replace(new RegExp(/\w/), (s) => s.toUpperCase());
|
|
49
|
+
}
|
|
50
|
+
exports.toPascalCase = toPascalCase;
|
|
51
|
+
/**
|
|
52
|
+
* Function to modify each line of a text, preserving the line break style (`\n` or `\r\n`)
|
|
53
|
+
*/
|
|
54
|
+
function modifyLines(text, replacementFn) {
|
|
55
|
+
let idx = 0;
|
|
56
|
+
return text
|
|
57
|
+
.split('\r\n')
|
|
58
|
+
.map((l1) => l1
|
|
59
|
+
.split('\n')
|
|
60
|
+
.map((line) => replacementFn(line, idx++))
|
|
61
|
+
.join('\n'))
|
|
62
|
+
.join('\r\n');
|
|
63
|
+
}
|
|
64
|
+
exports.modifyLines = modifyLines;
|
|
40
65
|
/**
|
|
41
66
|
* Return true if a specific node could be a component.
|
|
42
67
|
* This is not a 100% sure test as it'll return false for any component that does not match the standard format for a component
|
|
43
68
|
*/
|
|
44
69
|
function isPossibleComponent(node) {
|
|
45
|
-
|
|
46
|
-
return !!((_a = node.tag) === null || _a === void 0 ? void 0 : _a[0].match(/[A-Z]/)) || !!((_b = node.tag) === null || _b === void 0 ? void 0 : _b.match(/.+[.][A-Z]/));
|
|
70
|
+
return !!node.tag?.[0].match(/[A-Z]/) || !!node.tag?.match(/.+[.][A-Z]/);
|
|
47
71
|
}
|
|
48
72
|
exports.isPossibleComponent = isPossibleComponent;
|
|
49
73
|
/** Flattens an array */
|
|
@@ -69,6 +93,18 @@ function isBeforeOrEqualToPosition(position, positionToTest) {
|
|
|
69
93
|
(positionToTest.line === position.line && positionToTest.character <= position.character));
|
|
70
94
|
}
|
|
71
95
|
exports.isBeforeOrEqualToPosition = isBeforeOrEqualToPosition;
|
|
96
|
+
/**
|
|
97
|
+
* Get all matches of a regexp.
|
|
98
|
+
*/
|
|
99
|
+
function getRegExpMatches(regex, str) {
|
|
100
|
+
const matches = [];
|
|
101
|
+
let match;
|
|
102
|
+
while ((match = regex.exec(str))) {
|
|
103
|
+
matches.push(match);
|
|
104
|
+
}
|
|
105
|
+
return matches;
|
|
106
|
+
}
|
|
107
|
+
exports.getRegExpMatches = getRegExpMatches;
|
|
72
108
|
/**
|
|
73
109
|
* Debounces a function but cancels previous invocation only if
|
|
74
110
|
* a second function determines it should.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrojs/language-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.1",
|
|
4
4
|
"author": "withastro",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"test": "cross-env TS_NODE_TRANSPILE_ONLY=true mocha --timeout 20000 --require ts-node/register \"test/**/*.ts\" --exclude \"test/**/*.d.ts\""
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@astrojs/svelte-language-integration": "^0.1.
|
|
22
|
+
"@astrojs/svelte-language-integration": "^0.1.4",
|
|
23
23
|
"@vscode/emmet-helper": "^2.8.4",
|
|
24
24
|
"lodash": "^4.17.21",
|
|
25
25
|
"source-map": "^0.7.3",
|