@astrojs/language-server 0.16.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 +7 -0
- 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/plugins/astro/AstroPlugin.d.ts +1 -6
- package/dist/plugins/astro/AstroPlugin.js +0 -82
- package/dist/plugins/css/CSSPlugin.d.ts +5 -5
- package/dist/plugins/css/CSSPlugin.js +36 -31
- 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 +1 -0
- package/dist/plugins/typescript/TypeScriptPlugin.d.ts +2 -3
- package/dist/plugins/typescript/TypeScriptPlugin.js +24 -110
- package/dist/plugins/typescript/features/CodeActionsProvider.d.ts +3 -1
- package/dist/plugins/typescript/features/CodeActionsProvider.js +11 -5
- package/dist/plugins/typescript/features/CompletionsProvider.d.ts +3 -2
- package/dist/plugins/typescript/features/CompletionsProvider.js +9 -15
- package/dist/plugins/typescript/features/DefinitionsProvider.d.ts +9 -0
- package/dist/plugins/typescript/features/DefinitionsProvider.js +36 -0
- package/dist/server.js +23 -15
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @astrojs/language-server
|
|
2
2
|
|
|
3
|
+
## 0.16.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ad5a5e5: Fix misc issues with Go To Definition
|
|
8
|
+
- 1bd790d: Updates config management, make sure to respect TypeScript settings when doing completions and quickfixes
|
|
9
|
+
|
|
3
10
|
## 0.16.0
|
|
4
11
|
|
|
5
12
|
### Minor Changes
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { VSCodeEmmetConfig } from '@vscode/emmet-helper';
|
|
2
|
-
import { LSConfig } from './interfaces';
|
|
2
|
+
import { LSConfig, LSCSSConfig, LSHTMLConfig, LSTypescriptConfig } from './interfaces';
|
|
3
|
+
import { Connection } from 'vscode-languageserver';
|
|
4
|
+
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
5
|
+
import { FormatCodeSettings, UserPreferences } from 'typescript';
|
|
6
|
+
export declare const defaultLSConfig: LSConfig;
|
|
3
7
|
declare type DeepPartial<T> = T extends Record<string, unknown> ? {
|
|
4
8
|
[P in keyof T]?: DeepPartial<T[P]>;
|
|
5
9
|
} : T;
|
|
@@ -9,25 +13,25 @@ declare type DeepPartial<T> = T extends Record<string, unknown> ? {
|
|
|
9
13
|
* For more info on this, see the [internal docs](../../../../../docs/internal/language-server/config.md)
|
|
10
14
|
*/
|
|
11
15
|
export declare class ConfigManager {
|
|
12
|
-
private
|
|
13
|
-
private
|
|
16
|
+
private globalConfig;
|
|
17
|
+
private documentSettings;
|
|
14
18
|
private isTrusted;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
private connection;
|
|
20
|
+
constructor(connection?: Connection);
|
|
21
|
+
updateConfig(): void;
|
|
22
|
+
removeDocument(scopeUri: string): void;
|
|
23
|
+
getConfig<T>(section: string, scopeUri: string): Promise<T>;
|
|
24
|
+
getEmmetConfig(document: TextDocument): Promise<VSCodeEmmetConfig>;
|
|
25
|
+
getTSFormatConfig(document: TextDocument): Promise<FormatCodeSettings>;
|
|
26
|
+
getTSPreferences(document: TextDocument): Promise<UserPreferences>;
|
|
18
27
|
/**
|
|
19
|
-
*
|
|
20
|
-
* @param key a string which is a path. Example: 'astro.diagnostics.enabled'.
|
|
28
|
+
* Return true if a plugin and an optional feature is enabled
|
|
21
29
|
*/
|
|
22
|
-
|
|
30
|
+
isEnabled(document: TextDocument, plugin: keyof LSConfig, feature?: keyof LSTypescriptConfig | keyof LSCSSConfig | keyof LSHTMLConfig): Promise<boolean>;
|
|
23
31
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
32
|
+
* Updating the global config should only be done in cases where the client doesn't support `workspace/configuration`
|
|
33
|
+
* or inside of tests
|
|
26
34
|
*/
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Get the entire user configuration
|
|
30
|
-
*/
|
|
31
|
-
getFullConfig(): Readonly<LSConfig>;
|
|
35
|
+
updateGlobalConfig(config: DeepPartial<LSConfig>): void;
|
|
32
36
|
}
|
|
33
37
|
export {};
|
|
@@ -1,43 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ConfigManager = void 0;
|
|
3
|
+
exports.ConfigManager = exports.defaultLSConfig = void 0;
|
|
4
4
|
const lodash_1 = require("lodash");
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
enabled: true,
|
|
8
|
-
diagnostics: { enabled: true },
|
|
9
|
-
rename: { enabled: true },
|
|
10
|
-
format: { enabled: true },
|
|
11
|
-
completions: { enabled: true },
|
|
12
|
-
hover: { enabled: true },
|
|
13
|
-
codeActions: { enabled: true },
|
|
14
|
-
selectionRange: { enabled: true },
|
|
15
|
-
},
|
|
5
|
+
const typescript_1 = require("typescript");
|
|
6
|
+
exports.defaultLSConfig = {
|
|
16
7
|
typescript: {
|
|
17
8
|
enabled: true,
|
|
18
9
|
diagnostics: { enabled: true },
|
|
19
10
|
hover: { enabled: true },
|
|
20
11
|
completions: { enabled: true },
|
|
21
12
|
definitions: { enabled: true },
|
|
22
|
-
findReferences: { enabled: true },
|
|
23
13
|
documentSymbols: { enabled: true },
|
|
24
14
|
codeActions: { enabled: true },
|
|
25
15
|
rename: { enabled: true },
|
|
26
|
-
selectionRange: { enabled: true },
|
|
27
16
|
signatureHelp: { enabled: true },
|
|
28
17
|
semanticTokens: { enabled: true },
|
|
29
|
-
implementation: { enabled: true },
|
|
30
|
-
typeDefinition: { enabled: true },
|
|
31
18
|
},
|
|
32
19
|
css: {
|
|
33
20
|
enabled: true,
|
|
34
|
-
diagnostics: { enabled: true },
|
|
35
21
|
hover: { enabled: true },
|
|
36
22
|
completions: { enabled: true, emmet: true },
|
|
37
23
|
documentColors: { enabled: true },
|
|
38
|
-
colorPresentations: { enabled: true },
|
|
39
24
|
documentSymbols: { enabled: true },
|
|
40
|
-
selectionRange: { enabled: true },
|
|
41
25
|
},
|
|
42
26
|
html: {
|
|
43
27
|
enabled: true,
|
|
@@ -45,8 +29,6 @@ const defaultLSConfig = {
|
|
|
45
29
|
completions: { enabled: true, emmet: true },
|
|
46
30
|
tagComplete: { enabled: true },
|
|
47
31
|
documentSymbols: { enabled: true },
|
|
48
|
-
renameTags: { enabled: true },
|
|
49
|
-
linkedEditing: { enabled: true },
|
|
50
32
|
},
|
|
51
33
|
};
|
|
52
34
|
/**
|
|
@@ -55,42 +37,126 @@ const defaultLSConfig = {
|
|
|
55
37
|
* For more info on this, see the [internal docs](../../../../../docs/internal/language-server/config.md)
|
|
56
38
|
*/
|
|
57
39
|
class ConfigManager {
|
|
58
|
-
constructor() {
|
|
59
|
-
this.
|
|
60
|
-
this.
|
|
40
|
+
constructor(connection) {
|
|
41
|
+
this.globalConfig = { astro: exports.defaultLSConfig };
|
|
42
|
+
this.documentSettings = {};
|
|
61
43
|
this.isTrusted = true;
|
|
44
|
+
this.connection = connection;
|
|
62
45
|
}
|
|
63
|
-
updateConfig(
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
// We might at some point in the future forget to synch config settings in all packages after updating the config.
|
|
67
|
-
this.config = (0, lodash_1.merge)({}, defaultLSConfig, this.config, config);
|
|
46
|
+
updateConfig() {
|
|
47
|
+
// Reset all cached document settings
|
|
48
|
+
this.documentSettings = {};
|
|
68
49
|
}
|
|
69
|
-
|
|
70
|
-
this.
|
|
50
|
+
removeDocument(scopeUri) {
|
|
51
|
+
delete this.documentSettings[scopeUri];
|
|
71
52
|
}
|
|
72
|
-
|
|
73
|
-
|
|
53
|
+
async getConfig(section, scopeUri) {
|
|
54
|
+
if (!this.connection) {
|
|
55
|
+
return this.globalConfig[section];
|
|
56
|
+
}
|
|
57
|
+
if (!this.documentSettings[scopeUri]) {
|
|
58
|
+
this.documentSettings[scopeUri] = {};
|
|
59
|
+
}
|
|
60
|
+
if (!this.documentSettings[scopeUri][section]) {
|
|
61
|
+
this.documentSettings[scopeUri][section] = await this.connection.workspace.getConfiguration({
|
|
62
|
+
scopeUri,
|
|
63
|
+
section,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return this.documentSettings[scopeUri][section];
|
|
74
67
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
68
|
+
async getEmmetConfig(document) {
|
|
69
|
+
const emmetConfig = (await this.getConfig('emmet', document.uri)) ?? {};
|
|
70
|
+
return emmetConfig;
|
|
71
|
+
}
|
|
72
|
+
async getTSFormatConfig(document) {
|
|
73
|
+
const formatConfig = (await this.getConfig('typescript.format', document.uri)) ?? {};
|
|
74
|
+
return {
|
|
75
|
+
// We can use \n here since the editor normalizes later on to its line endings.
|
|
76
|
+
newLineCharacter: '\n',
|
|
77
|
+
insertSpaceAfterCommaDelimiter: formatConfig.insertSpaceAfterCommaDelimiter ?? true,
|
|
78
|
+
insertSpaceAfterConstructor: formatConfig.insertSpaceAfterConstructor ?? false,
|
|
79
|
+
insertSpaceAfterSemicolonInForStatements: formatConfig.insertSpaceAfterSemicolonInForStatements ?? true,
|
|
80
|
+
insertSpaceBeforeAndAfterBinaryOperators: formatConfig.insertSpaceBeforeAndAfterBinaryOperators ?? true,
|
|
81
|
+
insertSpaceAfterKeywordsInControlFlowStatements: formatConfig.insertSpaceAfterKeywordsInControlFlowStatements ?? true,
|
|
82
|
+
insertSpaceAfterFunctionKeywordForAnonymousFunctions: formatConfig.insertSpaceAfterFunctionKeywordForAnonymousFunctions ?? true,
|
|
83
|
+
insertSpaceBeforeFunctionParenthesis: formatConfig.insertSpaceBeforeFunctionParenthesis ?? false,
|
|
84
|
+
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: formatConfig.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis ?? false,
|
|
85
|
+
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: formatConfig.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets ?? false,
|
|
86
|
+
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: formatConfig.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces ?? true,
|
|
87
|
+
insertSpaceAfterOpeningAndBeforeClosingEmptyBraces: formatConfig.insertSpaceAfterOpeningAndBeforeClosingEmptyBraces ?? true,
|
|
88
|
+
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: formatConfig.insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces ?? false,
|
|
89
|
+
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: formatConfig.insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces ?? false,
|
|
90
|
+
insertSpaceAfterTypeAssertion: formatConfig.insertSpaceAfterTypeAssertion ?? false,
|
|
91
|
+
placeOpenBraceOnNewLineForFunctions: formatConfig.placeOpenBraceOnNewLineForFunctions ?? false,
|
|
92
|
+
placeOpenBraceOnNewLineForControlBlocks: formatConfig.placeOpenBraceOnNewLineForControlBlocks ?? false,
|
|
93
|
+
semicolons: formatConfig.semicolons ?? typescript_1.SemicolonPreference.Ignore,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
async getTSPreferences(document) {
|
|
97
|
+
const config = (await this.getConfig('typescript', document.uri)) ?? {};
|
|
98
|
+
const preferences = (await this.getConfig('typescript.preferences', document.uri)) ?? {};
|
|
99
|
+
return {
|
|
100
|
+
quotePreference: getQuoteStylePreference(preferences),
|
|
101
|
+
importModuleSpecifierPreference: getImportModuleSpecifierPreference(preferences),
|
|
102
|
+
importModuleSpecifierEnding: getImportModuleSpecifierEndingPreference(preferences),
|
|
103
|
+
allowTextChangesInNewFiles: document.uri.startsWith('file://'),
|
|
104
|
+
providePrefixAndSuffixTextForRename: (preferences.renameShorthandProperties ?? true) === false ? false : preferences.useAliasesForRenames ?? true,
|
|
105
|
+
includeAutomaticOptionalChainCompletions: config.suggest?.includeAutomaticOptionalChainCompletions ?? true,
|
|
106
|
+
includeCompletionsForImportStatements: config.suggest?.includeCompletionsForImportStatements ?? true,
|
|
107
|
+
includeCompletionsWithSnippetText: config.suggest?.includeCompletionsWithSnippetText ?? true,
|
|
108
|
+
includeCompletionsForModuleExports: config.suggest?.autoImports ?? true,
|
|
109
|
+
allowIncompleteCompletions: true,
|
|
110
|
+
includeCompletionsWithInsertText: true,
|
|
111
|
+
};
|
|
81
112
|
}
|
|
82
113
|
/**
|
|
83
|
-
*
|
|
84
|
-
* @param key a string which is a path. Example: 'astro.diagnostics.enable'.
|
|
114
|
+
* Return true if a plugin and an optional feature is enabled
|
|
85
115
|
*/
|
|
86
|
-
|
|
87
|
-
|
|
116
|
+
async isEnabled(document, plugin, feature) {
|
|
117
|
+
const config = await this.getConfig('astro', document.uri);
|
|
118
|
+
return feature ? config[plugin].enabled && config[plugin][feature].enabled : config[plugin].enabled;
|
|
88
119
|
}
|
|
89
120
|
/**
|
|
90
|
-
*
|
|
121
|
+
* Updating the global config should only be done in cases where the client doesn't support `workspace/configuration`
|
|
122
|
+
* or inside of tests
|
|
91
123
|
*/
|
|
92
|
-
|
|
93
|
-
|
|
124
|
+
updateGlobalConfig(config) {
|
|
125
|
+
this.globalConfig.astro = (0, lodash_1.merge)({}, exports.defaultLSConfig, this.globalConfig.astro, config);
|
|
94
126
|
}
|
|
95
127
|
}
|
|
96
128
|
exports.ConfigManager = ConfigManager;
|
|
129
|
+
function getQuoteStylePreference(config) {
|
|
130
|
+
switch (config.quoteStyle) {
|
|
131
|
+
case 'single':
|
|
132
|
+
return 'single';
|
|
133
|
+
case 'double':
|
|
134
|
+
return 'double';
|
|
135
|
+
default:
|
|
136
|
+
return 'auto';
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function getImportModuleSpecifierPreference(config) {
|
|
140
|
+
switch (config.importModuleSpecifier) {
|
|
141
|
+
case 'project-relative':
|
|
142
|
+
return 'project-relative';
|
|
143
|
+
case 'relative':
|
|
144
|
+
return 'relative';
|
|
145
|
+
case 'non-relative':
|
|
146
|
+
return 'non-relative';
|
|
147
|
+
default:
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function getImportModuleSpecifierEndingPreference(config) {
|
|
152
|
+
switch (config.importModuleSpecifierEnding) {
|
|
153
|
+
case 'minimal':
|
|
154
|
+
return 'minimal';
|
|
155
|
+
case 'index':
|
|
156
|
+
return 'index';
|
|
157
|
+
case 'js':
|
|
158
|
+
return 'js';
|
|
159
|
+
default:
|
|
160
|
+
return 'auto';
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -3,35 +3,10 @@
|
|
|
3
3
|
* Make sure that this is kept in sync with the `package.json` of the VS Code extension
|
|
4
4
|
*/
|
|
5
5
|
export interface LSConfig {
|
|
6
|
-
astro: LSAstroConfig;
|
|
7
6
|
typescript: LSTypescriptConfig;
|
|
8
7
|
html: LSHTMLConfig;
|
|
9
8
|
css: LSCSSConfig;
|
|
10
9
|
}
|
|
11
|
-
export interface LSAstroConfig {
|
|
12
|
-
enabled: boolean;
|
|
13
|
-
diagnostics: {
|
|
14
|
-
enabled: boolean;
|
|
15
|
-
};
|
|
16
|
-
format: {
|
|
17
|
-
enabled: boolean;
|
|
18
|
-
};
|
|
19
|
-
rename: {
|
|
20
|
-
enabled: boolean;
|
|
21
|
-
};
|
|
22
|
-
completions: {
|
|
23
|
-
enabled: boolean;
|
|
24
|
-
};
|
|
25
|
-
hover: {
|
|
26
|
-
enabled: boolean;
|
|
27
|
-
};
|
|
28
|
-
codeActions: {
|
|
29
|
-
enabled: boolean;
|
|
30
|
-
};
|
|
31
|
-
selectionRange: {
|
|
32
|
-
enabled: boolean;
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
10
|
export interface LSTypescriptConfig {
|
|
36
11
|
enabled: boolean;
|
|
37
12
|
diagnostics: {
|
|
@@ -46,9 +21,6 @@ export interface LSTypescriptConfig {
|
|
|
46
21
|
completions: {
|
|
47
22
|
enabled: boolean;
|
|
48
23
|
};
|
|
49
|
-
findReferences: {
|
|
50
|
-
enabled: boolean;
|
|
51
|
-
};
|
|
52
24
|
definitions: {
|
|
53
25
|
enabled: boolean;
|
|
54
26
|
};
|
|
@@ -58,21 +30,12 @@ export interface LSTypescriptConfig {
|
|
|
58
30
|
rename: {
|
|
59
31
|
enabled: boolean;
|
|
60
32
|
};
|
|
61
|
-
selectionRange: {
|
|
62
|
-
enabled: boolean;
|
|
63
|
-
};
|
|
64
33
|
signatureHelp: {
|
|
65
34
|
enabled: boolean;
|
|
66
35
|
};
|
|
67
36
|
semanticTokens: {
|
|
68
37
|
enabled: boolean;
|
|
69
38
|
};
|
|
70
|
-
implementation: {
|
|
71
|
-
enabled: boolean;
|
|
72
|
-
};
|
|
73
|
-
typeDefinition: {
|
|
74
|
-
enabled: boolean;
|
|
75
|
-
};
|
|
76
39
|
}
|
|
77
40
|
export interface LSHTMLConfig {
|
|
78
41
|
enabled: boolean;
|
|
@@ -89,18 +52,9 @@ export interface LSHTMLConfig {
|
|
|
89
52
|
documentSymbols: {
|
|
90
53
|
enabled: boolean;
|
|
91
54
|
};
|
|
92
|
-
renameTags: {
|
|
93
|
-
enabled: boolean;
|
|
94
|
-
};
|
|
95
|
-
linkedEditing: {
|
|
96
|
-
enabled: boolean;
|
|
97
|
-
};
|
|
98
55
|
}
|
|
99
56
|
export interface LSCSSConfig {
|
|
100
57
|
enabled: boolean;
|
|
101
|
-
diagnostics: {
|
|
102
|
-
enabled: boolean;
|
|
103
|
-
};
|
|
104
58
|
hover: {
|
|
105
59
|
enabled: boolean;
|
|
106
60
|
};
|
|
@@ -111,13 +65,7 @@ export interface LSCSSConfig {
|
|
|
111
65
|
documentColors: {
|
|
112
66
|
enabled: boolean;
|
|
113
67
|
};
|
|
114
|
-
colorPresentations: {
|
|
115
|
-
enabled: boolean;
|
|
116
|
-
};
|
|
117
68
|
documentSymbols: {
|
|
118
69
|
enabled: boolean;
|
|
119
70
|
};
|
|
120
|
-
selectionRange: {
|
|
121
|
-
enabled: boolean;
|
|
122
|
-
};
|
|
123
71
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CompletionContext,
|
|
1
|
+
import { CompletionContext, FoldingRange, Position } from 'vscode-languageserver';
|
|
2
2
|
import { ConfigManager } from '../../core/config';
|
|
3
3
|
import { AstroDocument, DocumentManager } from '../../core/documents';
|
|
4
4
|
import { AppCompletionList, Plugin } from '../interfaces';
|
|
@@ -10,9 +10,4 @@ export declare class AstroPlugin implements Plugin {
|
|
|
10
10
|
constructor(docManager: DocumentManager, configManager: ConfigManager, workspaceUris: string[]);
|
|
11
11
|
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): Promise<AppCompletionList | null>;
|
|
12
12
|
getFoldingRanges(document: AstroDocument): FoldingRange[];
|
|
13
|
-
getDefinitions(document: AstroDocument, position: Position): Promise<DefinitionLink[]>;
|
|
14
|
-
private isInsideFrontmatter;
|
|
15
|
-
private isComponentTag;
|
|
16
|
-
private getDefinitionsForComponentName;
|
|
17
|
-
private getImportSpecifierForIdentifier;
|
|
18
13
|
}
|
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.AstroPlugin = void 0;
|
|
7
|
-
const typescript_1 = __importDefault(require("typescript"));
|
|
8
4
|
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
9
|
-
const documents_1 = require("../../core/documents");
|
|
10
|
-
const utils_1 = require("../../utils");
|
|
11
5
|
const LanguageServiceManager_1 = require("../typescript/LanguageServiceManager");
|
|
12
|
-
const utils_2 = require("../typescript/utils");
|
|
13
6
|
const CompletionsProvider_1 = require("./features/CompletionsProvider");
|
|
14
7
|
class AstroPlugin {
|
|
15
8
|
constructor(docManager, configManager, workspaceUris) {
|
|
@@ -40,80 +33,5 @@ class AstroPlugin {
|
|
|
40
33
|
},
|
|
41
34
|
];
|
|
42
35
|
}
|
|
43
|
-
async getDefinitions(document, position) {
|
|
44
|
-
if (this.isInsideFrontmatter(document, position)) {
|
|
45
|
-
return [];
|
|
46
|
-
}
|
|
47
|
-
const offset = document.offsetAt(position);
|
|
48
|
-
const html = document.html;
|
|
49
|
-
const node = html.findNodeAt(offset);
|
|
50
|
-
if (!this.isComponentTag(node)) {
|
|
51
|
-
return [];
|
|
52
|
-
}
|
|
53
|
-
const [componentName] = node.tag.split(':');
|
|
54
|
-
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
|
55
|
-
const defs = this.getDefinitionsForComponentName(document, lang, componentName);
|
|
56
|
-
if (!defs || !defs.length) {
|
|
57
|
-
return [];
|
|
58
|
-
}
|
|
59
|
-
const startRange = vscode_languageserver_1.Range.create(vscode_languageserver_1.Position.create(0, 0), vscode_languageserver_1.Position.create(0, 0));
|
|
60
|
-
const links = defs.map((def) => {
|
|
61
|
-
const defFilePath = (0, utils_2.ensureRealFilePath)(def.fileName);
|
|
62
|
-
return vscode_languageserver_1.LocationLink.create((0, utils_1.pathToUrl)(defFilePath), startRange, startRange);
|
|
63
|
-
});
|
|
64
|
-
return links;
|
|
65
|
-
}
|
|
66
|
-
isInsideFrontmatter(document, position) {
|
|
67
|
-
return (0, documents_1.isInsideFrontmatter)(document.getText(), document.offsetAt(position));
|
|
68
|
-
}
|
|
69
|
-
isComponentTag(node) {
|
|
70
|
-
if (!node.tag) {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
const firstChar = node.tag[0];
|
|
74
|
-
return /[A-Z]/.test(firstChar);
|
|
75
|
-
}
|
|
76
|
-
getDefinitionsForComponentName(document, lang, componentName) {
|
|
77
|
-
const filePath = (0, utils_1.urlToPath)(document.uri);
|
|
78
|
-
const tsFilePath = (0, utils_2.toVirtualAstroFilePath)(filePath);
|
|
79
|
-
const program = lang.getProgram();
|
|
80
|
-
const sourceFile = program?.getSourceFile(tsFilePath);
|
|
81
|
-
if (!sourceFile) {
|
|
82
|
-
return undefined;
|
|
83
|
-
}
|
|
84
|
-
const specifier = this.getImportSpecifierForIdentifier(sourceFile, componentName);
|
|
85
|
-
if (!specifier) {
|
|
86
|
-
return [];
|
|
87
|
-
}
|
|
88
|
-
const defs = lang.getDefinitionAtPosition(tsFilePath, specifier.getStart());
|
|
89
|
-
if (!defs) {
|
|
90
|
-
return undefined;
|
|
91
|
-
}
|
|
92
|
-
return defs;
|
|
93
|
-
}
|
|
94
|
-
getImportSpecifierForIdentifier(sourceFile, identifier) {
|
|
95
|
-
let importSpecifier = undefined;
|
|
96
|
-
typescript_1.default.forEachChild(sourceFile, (tsNode) => {
|
|
97
|
-
if (typescript_1.default.isImportDeclaration(tsNode)) {
|
|
98
|
-
if (tsNode.importClause) {
|
|
99
|
-
const { name, namedBindings } = tsNode.importClause;
|
|
100
|
-
if (name && name.getText() === identifier) {
|
|
101
|
-
importSpecifier = tsNode.moduleSpecifier;
|
|
102
|
-
return true;
|
|
103
|
-
}
|
|
104
|
-
else if (namedBindings && namedBindings.kind === typescript_1.default.SyntaxKind.NamedImports) {
|
|
105
|
-
const elements = namedBindings.elements;
|
|
106
|
-
for (let elem of elements) {
|
|
107
|
-
if (elem.name.getText() === identifier) {
|
|
108
|
-
importSpecifier = tsNode.moduleSpecifier;
|
|
109
|
-
return true;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
return importSpecifier;
|
|
117
|
-
}
|
|
118
36
|
}
|
|
119
37
|
exports.AstroPlugin = AstroPlugin;
|
|
@@ -8,14 +8,14 @@ export declare class CSSPlugin implements Plugin {
|
|
|
8
8
|
private cssDocuments;
|
|
9
9
|
private triggerCharacters;
|
|
10
10
|
constructor(configManager: ConfigManager);
|
|
11
|
-
doHover(document: AstroDocument, position: Position): Hover | null
|
|
11
|
+
doHover(document: AstroDocument, position: Position): Promise<Hover | null>;
|
|
12
12
|
private doHoverInternal;
|
|
13
|
-
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): CompletionList | null
|
|
13
|
+
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): Promise<CompletionList | null>;
|
|
14
14
|
private getCompletionsInternal;
|
|
15
|
-
getDocumentColors(document: AstroDocument): ColorInformation[]
|
|
16
|
-
getColorPresentations(document: AstroDocument, range: Range, color: Color): ColorPresentation[]
|
|
15
|
+
getDocumentColors(document: AstroDocument): Promise<ColorInformation[]>;
|
|
16
|
+
getColorPresentations(document: AstroDocument, range: Range, color: Color): Promise<ColorPresentation[]>;
|
|
17
17
|
getFoldingRanges(document: AstroDocument): FoldingRange[] | null;
|
|
18
|
-
getDocumentSymbols(document: AstroDocument): SymbolInformation[]
|
|
18
|
+
getDocumentSymbols(document: AstroDocument): Promise<SymbolInformation[]>;
|
|
19
19
|
private inStyleAttributeWithoutInterpolation;
|
|
20
20
|
/**
|
|
21
21
|
* Get the associated CSS Document for a style tag
|
|
@@ -17,8 +17,8 @@ class CSSPlugin {
|
|
|
17
17
|
this.triggerCharacters = new Set(['.', ':', '-', '/']);
|
|
18
18
|
this.configManager = configManager;
|
|
19
19
|
}
|
|
20
|
-
doHover(document, position) {
|
|
21
|
-
if (!this.featureEnabled('hover')) {
|
|
20
|
+
async doHover(document, position) {
|
|
21
|
+
if (!(await this.featureEnabled(document, 'hover'))) {
|
|
22
22
|
return null;
|
|
23
23
|
}
|
|
24
24
|
if ((0, documents_1.isInsideFrontmatter)(document.getText(), document.offsetAt(position))) {
|
|
@@ -53,8 +53,8 @@ class CSSPlugin {
|
|
|
53
53
|
const hoverInfo = (0, language_service_1.getLanguageService)(extractLanguage(cssDocument)).doHover(cssDocument, cssDocument.getGeneratedPosition(position), cssDocument.stylesheet);
|
|
54
54
|
return hoverInfo ? (0, documents_1.mapHoverToParent)(cssDocument, hoverInfo) : hoverInfo;
|
|
55
55
|
}
|
|
56
|
-
getCompletions(document, position, completionContext) {
|
|
57
|
-
if (!this.featureEnabled('completions')) {
|
|
56
|
+
async getCompletions(document, position, completionContext) {
|
|
57
|
+
if (!(await this.featureEnabled(document, 'completions'))) {
|
|
58
58
|
return null;
|
|
59
59
|
}
|
|
60
60
|
if ((0, documents_1.isInsideFrontmatter)(document.getText(), document.offsetAt(position))) {
|
|
@@ -77,7 +77,7 @@ class CSSPlugin {
|
|
|
77
77
|
}
|
|
78
78
|
if (this.inStyleAttributeWithoutInterpolation(attributeContext, document.getText())) {
|
|
79
79
|
const [start, end] = attributeContext.valueRange;
|
|
80
|
-
return this.getCompletionsInternal(document, position, new StyleAttributeDocument_1.StyleAttributeDocument(document, start, end));
|
|
80
|
+
return await this.getCompletionsInternal(document, position, new StyleAttributeDocument_1.StyleAttributeDocument(document, start, end));
|
|
81
81
|
}
|
|
82
82
|
// If we're not in a style attribute, instead give completions for ids and classes used in the current document
|
|
83
83
|
else if ((attributeContext.name == 'id' || attributeContext.name == 'class') && attributeContext.inValue) {
|
|
@@ -87,13 +87,14 @@ class CSSPlugin {
|
|
|
87
87
|
return null;
|
|
88
88
|
}
|
|
89
89
|
const cssDocument = this.getCSSDocumentForStyleTag(styleTag, document);
|
|
90
|
-
return this.getCompletionsInternal(document, position, cssDocument);
|
|
90
|
+
return await this.getCompletionsInternal(document, position, cssDocument);
|
|
91
91
|
}
|
|
92
|
-
getCompletionsInternal(document, position, cssDocument) {
|
|
92
|
+
async getCompletionsInternal(document, position, cssDocument) {
|
|
93
|
+
const emmetConfig = await this.configManager.getEmmetConfig(document);
|
|
93
94
|
if (isSASS(cssDocument)) {
|
|
94
95
|
// The CSS language service does not support SASS (not to be confused with SCSS)
|
|
95
96
|
// however we can at least still at least provide Emmet completions in SASS blocks
|
|
96
|
-
return (0, emmet_helper_1.doComplete)(document, position, 'sass',
|
|
97
|
+
return (0, emmet_helper_1.doComplete)(document, position, 'sass', emmetConfig) || null;
|
|
97
98
|
}
|
|
98
99
|
const cssLang = extractLanguage(cssDocument);
|
|
99
100
|
const langService = (0, language_service_1.getLanguageService)(cssLang);
|
|
@@ -101,29 +102,32 @@ class CSSPlugin {
|
|
|
101
102
|
isIncomplete: false,
|
|
102
103
|
items: [],
|
|
103
104
|
};
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
const extensionConfig = await this.configManager.getConfig('astro', document.uri);
|
|
106
|
+
if (extensionConfig.css.completions.emmet) {
|
|
107
|
+
langService.setCompletionParticipants([
|
|
108
|
+
{
|
|
109
|
+
onCssProperty: (context) => {
|
|
110
|
+
if (context?.propertyName) {
|
|
111
|
+
emmetResults =
|
|
112
|
+
(0, emmet_helper_1.doComplete)(cssDocument, cssDocument.getGeneratedPosition(position), (0, language_service_1.getLanguage)(cssLang), emmetConfig) || emmetResults;
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
onCssPropertyValue: (context) => {
|
|
116
|
+
if (context?.propertyValue) {
|
|
117
|
+
emmetResults =
|
|
118
|
+
(0, emmet_helper_1.doComplete)(cssDocument, cssDocument.getGeneratedPosition(position), (0, language_service_1.getLanguage)(cssLang), emmetConfig) || emmetResults;
|
|
119
|
+
}
|
|
120
|
+
},
|
|
111
121
|
},
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
emmetResults =
|
|
115
|
-
(0, emmet_helper_1.doComplete)(cssDocument, cssDocument.getGeneratedPosition(position), (0, language_service_1.getLanguage)(cssLang), this.configManager.getEmmetConfig()) || emmetResults;
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
]);
|
|
122
|
+
]);
|
|
123
|
+
}
|
|
120
124
|
const results = langService.doComplete(cssDocument, cssDocument.getGeneratedPosition(position), cssDocument.stylesheet);
|
|
121
125
|
return vscode_languageserver_1.CompletionList.create([...(results ? results.items : []), ...emmetResults.items].map((completionItem) => (0, documents_1.mapCompletionItemToOriginal)(cssDocument, completionItem)),
|
|
122
126
|
// Emmet completions change on every keystroke, so they are never complete
|
|
123
127
|
emmetResults.items.length > 0);
|
|
124
128
|
}
|
|
125
|
-
getDocumentColors(document) {
|
|
126
|
-
if (!this.featureEnabled('documentColors')) {
|
|
129
|
+
async getDocumentColors(document) {
|
|
130
|
+
if (!(await this.featureEnabled(document, 'documentColors'))) {
|
|
127
131
|
return [];
|
|
128
132
|
}
|
|
129
133
|
const allColorInfo = this.getCSSDocumentsForDocument(document).map((cssDoc) => {
|
|
@@ -138,8 +142,8 @@ class CSSPlugin {
|
|
|
138
142
|
});
|
|
139
143
|
return (0, lodash_1.flatten)(allColorInfo);
|
|
140
144
|
}
|
|
141
|
-
getColorPresentations(document, range, color) {
|
|
142
|
-
if (!this.featureEnabled('
|
|
145
|
+
async getColorPresentations(document, range, color) {
|
|
146
|
+
if (!(await this.featureEnabled(document, 'documentColors'))) {
|
|
143
147
|
return [];
|
|
144
148
|
}
|
|
145
149
|
const allColorPres = this.getCSSDocumentsForDocument(document).map((cssDoc) => {
|
|
@@ -163,8 +167,8 @@ class CSSPlugin {
|
|
|
163
167
|
});
|
|
164
168
|
return (0, lodash_1.flatten)(allFoldingRanges);
|
|
165
169
|
}
|
|
166
|
-
getDocumentSymbols(document) {
|
|
167
|
-
if (!this.featureEnabled('documentSymbols')) {
|
|
170
|
+
async getDocumentSymbols(document) {
|
|
171
|
+
if (!(await this.featureEnabled(document, 'documentSymbols'))) {
|
|
168
172
|
return [];
|
|
169
173
|
}
|
|
170
174
|
const allDocumentSymbols = this.getCSSDocumentsForDocument(document).map((cssDoc) => {
|
|
@@ -210,8 +214,9 @@ class CSSPlugin {
|
|
|
210
214
|
return (0, documents_1.isInTag)(position, styleTag);
|
|
211
215
|
});
|
|
212
216
|
}
|
|
213
|
-
featureEnabled(feature) {
|
|
214
|
-
return this.configManager.
|
|
217
|
+
async featureEnabled(document, feature) {
|
|
218
|
+
return ((await this.configManager.isEnabled(document, 'css')) &&
|
|
219
|
+
(await this.configManager.isEnabled(document, 'css', feature)));
|
|
215
220
|
}
|
|
216
221
|
}
|
|
217
222
|
exports.CSSPlugin = CSSPlugin;
|
|
@@ -10,14 +10,14 @@ export declare class HTMLPlugin implements Plugin {
|
|
|
10
10
|
private styleScriptTemplate;
|
|
11
11
|
private configManager;
|
|
12
12
|
constructor(configManager: ConfigManager);
|
|
13
|
-
doHover(document: AstroDocument, position: Position): Hover | null
|
|
13
|
+
doHover(document: AstroDocument, position: Position): Promise<Hover | null>;
|
|
14
14
|
/**
|
|
15
15
|
* Get HTML completions
|
|
16
16
|
*/
|
|
17
|
-
getCompletions(document: AstroDocument, position: Position): CompletionList | null
|
|
17
|
+
getCompletions(document: AstroDocument, position: Position): Promise<CompletionList | null>;
|
|
18
18
|
getFoldingRanges(document: AstroDocument): FoldingRange[] | null;
|
|
19
|
-
doTagComplete(document: AstroDocument, position: Position): string | null
|
|
20
|
-
getDocumentSymbols(document: AstroDocument): SymbolInformation[]
|
|
19
|
+
doTagComplete(document: AstroDocument, position: Position): Promise<string | null>;
|
|
20
|
+
getDocumentSymbols(document: AstroDocument): Promise<SymbolInformation[]>;
|
|
21
21
|
/**
|
|
22
22
|
* Get lang completions for style tags (ex: `<style lang="scss">`)
|
|
23
23
|
*/
|