From 1f822c8e518132b01d7eda665f6bf7bc254780a7 Mon Sep 17 00:00:00 2001 From: Seivan Heidari Date: Thu, 31 Oct 2019 10:36:54 +0100 Subject: [PATCH] Adding better debugging for testing themes missing tags and which scopes didn't map. Since this file is no longer being pushed upstream, double down on monads. --- editors/code/src/highlighting.ts | 5 +- editors/code/src/scopes.ts | 87 +++++++++++++++++-------------- editors/code/src/scopes_mapper.ts | 11 ++-- 3 files changed, 58 insertions(+), 45 deletions(-) diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts index b7dffaff53f..dad99254ebf 100644 --- a/editors/code/src/highlighting.ts +++ b/editors/code/src/highlighting.ts @@ -73,7 +73,10 @@ export class Highlighter { return [tag, decor]; } else { - console.log('Missing theme for: ' + tag); + console.log(' '); + console.log('Missing theme for: <"' + tag + '"> for following mapped scopes:') + console.log(scopesMapper.find(tag)) + console.log(' '); const color = new vscode.ThemeColor('ralsp.' + tag); const decor = vscode.window.createTextEditorDecorationType({ color, diff --git a/editors/code/src/scopes.ts b/editors/code/src/scopes.ts index 470ee716ff2..76cbbd84e33 100644 --- a/editors/code/src/scopes.ts +++ b/editors/code/src/scopes.ts @@ -41,61 +41,72 @@ export function load() { } } +function filterThemeExtensions(extension: vscode.Extension): boolean { + return extension.extensionKind === vscode.ExtensionKind.UI && + extension.packageJSON.contributes && + extension.packageJSON.contributes.themes +} + + + // Find current theme on disk function loadThemeNamed(themeName: string) { const themePaths = vscode.extensions.all - .filter(extension => extension.extensionKind === vscode.ExtensionKind.UI) - .filter(extension => extension.packageJSON.contributes) - .filter(extension => extension.packageJSON.contributes.themes) + .filter(filterThemeExtensions) .reduce((list, extension) => { const paths = extension.packageJSON.contributes.themes .filter((element: any) => (element.id || element.label) === themeName) .map((element: any) => path.join(extension.extensionPath, element.path)) return list.concat(paths) - }, Array()); + }, Array()) - themePaths.forEach(loadThemeFile); + themePaths.forEach(loadThemeFile) + + const tokenColorCustomizations: [any] = [vscode.workspace.getConfiguration('editor').get('tokenColorCustomizations')] + + tokenColorCustomizations + .filter(custom => custom && custom.textMateRules) + .map(custom => custom.textMateRules) + .forEach(loadColors) - const customization: any = vscode.workspace.getConfiguration('editor').get('tokenColorCustomizations'); - if (customization && customization.textMateRules) { - loadColors(customization.textMateRules) - } } + function loadThemeFile(themePath: string) { + const themeContent = [themePath] + .filter(isFile) + .map(readFileText) + .map(parseJSON) + .filter(theme => theme) - if (checkFileExists(themePath)) { - const themeContentText: string = readFileText(themePath) + themeContent + .filter(theme => theme.tokenColors) + .map(theme => theme.tokenColors) + .forEach(loadColors) - const themeContent: any = JSON.parse(themeContentText) - - if (themeContent && themeContent.tokenColors) { - loadColors(themeContent.tokenColors) - if (themeContent.include) { - // parse included theme file - const includedThemePath: string = path.join(path.dirname(themePath), themeContent.include) - loadThemeFile(includedThemePath) - } - } - } + themeContent + .filter(theme => theme.include) + .map(theme => path.join(path.dirname(themePath), theme.include)) + .forEach(loadThemeFile) } + function mergeRuleSettings(defaultSetting: TextMateRuleSettings, override: TextMateRuleSettings): TextMateRuleSettings { - const mergedRule = defaultSetting; + const mergedRule = defaultSetting mergedRule.background = override.background || defaultSetting.background mergedRule.foreground = override.foreground || defaultSetting.foreground - mergedRule.fontStyle = override.fontStyle || defaultSetting.foreground; + mergedRule.fontStyle = override.fontStyle || defaultSetting.foreground - return mergedRule; + return mergedRule } function loadColors(textMateRules: TextMateRule[]): void { for (const rule of textMateRules) { if (typeof rule.scope === 'string') { - const existingRule = rules.get(rule.scope); + const existingRule = rules.get(rule.scope) if (existingRule) { rules.set(rule.scope, mergeRuleSettings(existingRule, rule.settings)) } @@ -104,7 +115,7 @@ function loadColors(textMateRules: TextMateRule[]): void { } } else if (rule.scope instanceof Array) { for (const scope of rule.scope) { - const existingRule = rules.get(scope); + const existingRule = rules.get(scope) if (existingRule) { rules.set(scope, mergeRuleSettings(existingRule, rule.settings)) } @@ -116,19 +127,15 @@ function loadColors(textMateRules: TextMateRule[]): void { } } -function checkFileExists(filePath: string): boolean { - - const stats = fs.statSync(filePath); - if (stats && stats.isFile()) { - return true; - } else { - // console.warn('no such file', filePath) - return false; - } - - +function isFile(filePath: string): boolean { + return [filePath].map(fs.statSync).every(stat => stat.isFile()) } -function readFileText(filePath: string, encoding: string = 'utf8'): string { - return fs.readFileSync(filePath, encoding); +function readFileText(filePath: string): string { + return fs.readFileSync(filePath, 'utf8') +} + +// Might need to replace with JSONC if a theme contains comments. +function parseJSON(content: string): any { + return JSON.parse(content) } \ No newline at end of file diff --git a/editors/code/src/scopes_mapper.ts b/editors/code/src/scopes_mapper.ts index 4534d8a32f4..19a4213d451 100644 --- a/editors/code/src/scopes_mapper.ts +++ b/editors/code/src/scopes_mapper.ts @@ -28,21 +28,24 @@ const defaultMapping = new Map([ ['module', ['entity.name.section', 'entity.other']] ] ) -function find(scope: string): string[] { + +// Temporary exported for debugging for now. +export function find(scope: string): string[] { return mappings.get(scope) || [] } export function toRule(scope: string, intoRule: (scope: string) => TextMateRuleSettings | undefined): TextMateRuleSettings | undefined { - return find(scope).map(intoRule).filter(rule => rule !== undefined)[0]; + return find(scope).map(intoRule).filter(rule => rule !== undefined)[0] } export function load() { const configuration = vscode.workspace .getConfiguration('rust-analyzer') - .get('scopeMappings') as Map | undefined || new Map() + .get('scopeMappings') as Map | undefined + || new Map() - mappings = new Map([...Array.from(defaultMapping.entries()), ...Array.from(configuration.entries())]); + mappings = new Map([...Array.from(defaultMapping.entries()), ...Array.from(configuration.entries())]) } \ No newline at end of file