@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 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 config;
13
- private emmetConfig;
16
+ private globalConfig;
17
+ private documentSettings;
14
18
  private isTrusted;
15
- updateConfig(config: DeepPartial<LSConfig>): void;
16
- updateEmmetConfig(config: VSCodeEmmetConfig): void;
17
- getEmmetConfig(): VSCodeEmmetConfig;
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
- * Whether or not specified setting is enabled
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
- enabled(key: string): boolean;
30
+ isEnabled(document: TextDocument, plugin: keyof LSConfig, feature?: keyof LSTypescriptConfig | keyof LSCSSConfig | keyof LSHTMLConfig): Promise<boolean>;
23
31
  /**
24
- * Get a specific setting value
25
- * @param key a string which is a path. Example: 'astro.diagnostics.enable'.
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
- get<T>(key: string): T;
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 defaultLSConfig = {
6
- astro: {
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.config = defaultLSConfig;
60
- this.emmetConfig = {};
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(config) {
64
- // Ideally we shouldn't need the merge here because all updates should be valid and complete configs.
65
- // But since those configs come from the client they might be out of synch with the valid config:
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
- updateEmmetConfig(config) {
70
- this.emmetConfig = config || {};
50
+ removeDocument(scopeUri) {
51
+ delete this.documentSettings[scopeUri];
71
52
  }
72
- getEmmetConfig() {
73
- return this.emmetConfig;
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
- * Whether or not specified setting is enabled
77
- * @param key a string which is a path. Example: 'astro.diagnostics.enabled'.
78
- */
79
- enabled(key) {
80
- return !!this.get(key);
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
- * Get a specific setting value
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
- get(key) {
87
- return (0, lodash_1.get)(this.config, key);
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
- * Get the entire user configuration
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
- getFullConfig() {
93
- return this.config;
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, DefinitionLink, FoldingRange, Position } from 'vscode-languageserver';
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', this.configManager.getEmmetConfig()) || null;
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
- langService.setCompletionParticipants([
105
- {
106
- onCssProperty: (context) => {
107
- if (context?.propertyName) {
108
- emmetResults =
109
- (0, emmet_helper_1.doComplete)(cssDocument, cssDocument.getGeneratedPosition(position), (0, language_service_1.getLanguage)(cssLang), this.configManager.getEmmetConfig()) || emmetResults;
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
- onCssPropertyValue: (context) => {
113
- if (context?.propertyValue) {
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('colorPresentations')) {
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.enabled('css.enabled') && this.configManager.enabled(`css.${feature}.enabled`);
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
  */