diff --git a/packages/monaco/src/browser/textmate/monaco-theme-registry.ts b/packages/monaco/src/browser/textmate/monaco-theme-registry.ts index 32ed0648e0050..62f2a1e232f32 100644 --- a/packages/monaco/src/browser/textmate/monaco-theme-registry.ts +++ b/packages/monaco/src/browser/textmate/monaco-theme-registry.ts @@ -17,6 +17,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ +import { injectable } from 'inversify'; import { IRawTheme, Registry, IRawThemeSetting } from 'vscode-textmate'; export interface ThemeMix extends IRawTheme, monaco.editor.IStandaloneThemeData { } @@ -24,6 +25,7 @@ export interface MixStandaloneTheme extends monaco.services.IStandaloneTheme { themeData: ThemeMix } +@injectable() export class MonacoThemeRegistry { getThemeData(): ThemeMix; @@ -53,7 +55,7 @@ export class MonacoThemeRegistry { /** * Register VS Code compatible themes */ - public register(json: any, includes?: { [includePath: string]: any }, givenName?: string, monacoBase?: monaco.editor.BuiltinTheme): ThemeMix { + register(json: any, includes?: { [includePath: string]: any }, givenName?: string, monacoBase?: monaco.editor.BuiltinTheme): ThemeMix { const name = givenName || json.name!; const result: ThemeMix = { name, @@ -96,19 +98,24 @@ export class MonacoThemeRegistry { for (const setting of result.settings) { this.transform(setting, rule => result.rules.push(rule)); } + + // the default rule (scope empty) is always the first rule. Ignore all other default rules. + const defaultTheme = monaco.services.StaticServices.standaloneThemeService.get()._knownThemes.get(result.base)!; + const foreground = result.colors['editor.foreground'] || defaultTheme.getColor('editor.foreground'); + const background = result.colors['editor.background'] || defaultTheme.getColor('editor.background'); + result.settings.unshift({ + settings: { + foreground: this.normalizeColor(foreground), + background: this.normalizeColor(background) + } + }); + const reg = new Registry(); reg.setTheme(result); result.encodedTokensColors = reg.getColorMap(); // index 0 has to be set to null as it is 'undefined' by default, but monaco code expects it to be null // eslint-disable-next-line no-null/no-null result.encodedTokensColors[0] = null!; - // index 1 and 2 are the default colors - if (result.colors && result.colors['editor.foreground']) { - result.encodedTokensColors[1] = result.colors['editor.foreground']; - } - if (result.colors && result.colors['editor.background']) { - result.encodedTokensColors[2] = result.colors['editor.background']; - } this.setTheme(givenName, result); } return result; @@ -128,17 +135,17 @@ export class MonacoThemeRegistry { } } - protected normalizeColor(color: string | undefined): string | undefined { + protected normalizeColor(color: string | monaco.color.Color | undefined): string | undefined { if (!color) { return undefined; } - color = color.replace(/^\#/, '').slice(0, 6); - if (color.length < 6) { + const normalized = String(color).replace(/^\#/, '').slice(0, 6); + if (normalized.length < 6) { // ignoring not normalized colors to avoid breaking token color indexes between monaco and vscode-textmate - console.error(`Color '${color}' is NOT normalized, it must have 6 positions.`); + console.error(`Color '${normalized}' is NOT normalized, it must have 6 positions.`); return undefined; } - return '#' + color; + return '#' + normalized; } }