Skip to content

Commit 84c7463

Browse files
authored
(feat) support html.customData (#1824)
from VS Code html language service #1821
1 parent 289d2b4 commit 84c7463

File tree

4 files changed

+70
-17
lines changed

4 files changed

+70
-17
lines changed

packages/language-server/src/ls-config.ts

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,13 @@ export interface CssConfig {
249249
hover?: any;
250250
}
251251

252+
/**
253+
* The config as the vscode-html-languageservice understands it
254+
*/
255+
export interface HTMLConfig {
256+
customData?: string[];
257+
}
258+
252259
type DeepPartial<T> = T extends CompilerWarningsSettings
253260
? T
254261
: {
@@ -273,6 +280,7 @@ export class LSConfigManager {
273280
private cssConfig: CssConfig | undefined;
274281
private scssConfig: CssConfig | undefined;
275282
private lessConfig: CssConfig | undefined;
283+
private htmlConfig: HTMLConfig | undefined;
276284
private isTrusted = true;
277285

278286
constructor() {
@@ -296,7 +304,7 @@ export class LSConfigManager {
296304
// TODO remove once we remove old transformation
297305
this.config.svelte.useNewTransformation = true;
298306

299-
this.listeners.forEach((listener) => listener(this));
307+
this.notifyListeners();
300308
}
301309

302310
/**
@@ -331,7 +339,7 @@ export class LSConfigManager {
331339

332340
updateEmmetConfig(config: VSCodeEmmetConfig): void {
333341
this.emmetConfig = config || {};
334-
this.listeners.forEach((listener) => listener(this));
342+
this.notifyListeners();
335343
}
336344

337345
getEmmetConfig(): VSCodeEmmetConfig {
@@ -340,7 +348,7 @@ export class LSConfigManager {
340348

341349
updatePrettierConfig(config: any): void {
342350
this.prettierConfig = config || {};
343-
this.listeners.forEach((listener) => listener(this));
351+
this.notifyListeners();
344352
}
345353

346354
getPrettierConfig(): any {
@@ -376,7 +384,7 @@ export class LSConfigManager {
376384
this._updateTsUserPreferences(lang, config[lang]);
377385
}
378386
});
379-
this.listeners.forEach((listener) => listener(this));
387+
this.notifyListeners();
380388
this.resolvedAutoImportExcludeCache.clear();
381389
}
382390

@@ -390,7 +398,7 @@ export class LSConfigManager {
390398

391399
updateIsTrusted(isTrusted: boolean): void {
392400
this.isTrusted = isTrusted;
393-
this.listeners.forEach((listener) => listener(this));
401+
this.notifyListeners();
394402
}
395403

396404
private _updateTsUserPreferences(lang: TsUserConfigLang, config: TSUserConfig) {
@@ -457,7 +465,7 @@ export class LSConfigManager {
457465

458466
updateCssConfig(config: CssConfig | undefined): void {
459467
this.cssConfig = config;
460-
this.listeners.forEach((listener) => listener(this));
468+
this.notifyListeners();
461469
}
462470

463471
getCssConfig(): CssConfig | undefined {
@@ -466,7 +474,7 @@ export class LSConfigManager {
466474

467475
updateScssConfig(config: CssConfig | undefined): void {
468476
this.scssConfig = config;
469-
this.listeners.forEach((listener) => listener(this));
477+
this.notifyListeners();
470478
}
471479

472480
getScssConfig(): CssConfig | undefined {
@@ -475,20 +483,29 @@ export class LSConfigManager {
475483

476484
updateLessConfig(config: CssConfig | undefined): void {
477485
this.lessConfig = config;
478-
this.listeners.forEach((listener) => listener(this));
486+
this.notifyListeners();
479487
}
480488

481489
getLessConfig(): CssConfig | undefined {
482490
return this.lessConfig;
483491
}
484492

493+
updateHTMLConfig(config: HTMLConfig | undefined): void {
494+
this.htmlConfig = config;
495+
this.notifyListeners();
496+
}
497+
498+
getHTMLConfig(): HTMLConfig | undefined {
499+
return this.htmlConfig;
500+
}
501+
485502
updateTsJsFormateConfig(config: Record<TsUserConfigLang, TSUserConfig>): void {
486503
(['typescript', 'javascript'] as const).forEach((lang) => {
487504
if (config[lang]) {
488505
this._updateTsFormatConfig(lang, config[lang]);
489506
}
490507
});
491-
this.listeners.forEach((listener) => listener(this));
508+
this.notifyListeners();
492509
}
493510

494511
private getDefaultFormatCodeOptions(): ts.FormatCodeSettings {
@@ -568,4 +585,15 @@ export class LSConfigManager {
568585
: ts.SemicolonPreference.Remove
569586
};
570587
}
588+
589+
private scheduledUpdate: NodeJS.Timeout | undefined;
590+
private notifyListeners() {
591+
if (this.scheduledUpdate) {
592+
clearTimeout(this.scheduledUpdate);
593+
}
594+
this.scheduledUpdate = setTimeout(() => {
595+
this.scheduledUpdate = undefined;
596+
this.listeners.forEach((listener) => listener(this));
597+
});
598+
}
571599
}

packages/language-server/src/plugins/html/HTMLPlugin.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import {
33
getLanguageService,
44
HTMLDocument,
55
CompletionItem as HtmlCompletionItem,
6-
Node
6+
Node,
7+
newHTMLDataProvider
78
} from 'vscode-html-languageservice';
89
import {
910
CompletionList,
@@ -32,23 +33,26 @@ import {
3233
LinkedEditingRangesProvider
3334
} from '../interfaces';
3435
import { isInsideMoustacheTag, toRange } from '../../lib/documents/utils';
35-
import { possiblyComponent } from '../../utils';
36+
import { isNotNullOrUndefined, possiblyComponent } from '../../utils';
3637
import { importPrettier } from '../../importPackage';
38+
import path from 'path';
39+
import { Logger } from '../../logger';
3740

3841
export class HTMLPlugin
3942
implements HoverProvider, CompletionsProvider, RenameProvider, LinkedEditingRangesProvider
4043
{
4144
__name = 'html';
42-
private configManager: LSConfigManager;
4345
private lang = getLanguageService({
44-
customDataProviders: [svelteHtmlDataProvider],
46+
customDataProviders: this.getCustomDataProviders(),
4547
useDefaultDataProvider: false
4648
});
4749
private documents = new WeakMap<Document, HTMLDocument>();
4850
private styleScriptTemplate = new Set(['template', 'style', 'script']);
4951

50-
constructor(docManager: DocumentManager, configManager: LSConfigManager) {
51-
this.configManager = configManager;
52+
constructor(docManager: DocumentManager, private configManager: LSConfigManager) {
53+
configManager.onChange(() =>
54+
this.lang.setDataProviders(false, this.getCustomDataProviders())
55+
);
5256
docManager.on('documentChange', (document) => {
5357
this.documents.set(document, document.html);
5458
});
@@ -323,6 +327,23 @@ export class HTMLPlugin
323327
return isAtStartTag || isAtEndTag;
324328
}
325329

330+
private getCustomDataProviders() {
331+
const providers =
332+
this.configManager
333+
.getHTMLConfig()
334+
?.customData?.map((customDataPath) => {
335+
try {
336+
const jsonPath = path.resolve(customDataPath);
337+
return newHTMLDataProvider(customDataPath, require(jsonPath));
338+
} catch (error) {
339+
Logger.error(error);
340+
}
341+
})
342+
.filter(isNotNullOrUndefined) ?? [];
343+
344+
return [svelteHtmlDataProvider].concat(providers);
345+
}
346+
326347
private featureEnabled(feature: keyof LSHTMLConfig) {
327348
return (
328349
this.configManager.enabled('html.enable') &&

packages/language-server/src/server.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ export function startServer(options?: LSOptions) {
149149
configManager.updateCssConfig(evt.initializationOptions?.configuration?.css);
150150
configManager.updateScssConfig(evt.initializationOptions?.configuration?.scss);
151151
configManager.updateLessConfig(evt.initializationOptions?.configuration?.less);
152+
configManager.updateHTMLConfig(evt.initializationOptions?.configuration?.html);
152153

153154
pluginHost.initialize({
154155
filterIncompleteCompletions:
@@ -311,6 +312,7 @@ export function startServer(options?: LSOptions) {
311312
configManager.updateCssConfig(settings.css);
312313
configManager.updateScssConfig(settings.scss);
313314
configManager.updateLessConfig(settings.less);
315+
configManager.updateHTMLConfig(settings.html);
314316
Logger.setDebug(settings.svelte?.['language-server']?.debug);
315317
});
316318

packages/svelte-vscode/src/extension.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ export function activateSvelteLanguageServer(context: ExtensionContext) {
149149
'typescript',
150150
'css',
151151
'less',
152-
'scss'
152+
'scss',
153+
'html'
153154
],
154155
fileEvents: workspace.createFileSystemWatcher('{**/*.js,**/*.ts}', false, false, false)
155156
},
@@ -162,7 +163,8 @@ export function activateSvelteLanguageServer(context: ExtensionContext) {
162163
javascript: workspace.getConfiguration('javascript'),
163164
css: workspace.getConfiguration('css'),
164165
less: workspace.getConfiguration('less'),
165-
scss: workspace.getConfiguration('scss')
166+
scss: workspace.getConfiguration('scss'),
167+
html: workspace.getConfiguration('html')
166168
},
167169
dontFilterIncompleteCompletions: true, // VSCode filters client side and is smarter at it than us
168170
isTrusted: (workspace as any).isTrusted

0 commit comments

Comments
 (0)