[themes] opt-in to semanticHighlighting

This commit is contained in:
Martin Aeschlimann 2020-03-13 21:55:39 +01:00
parent bf8fb5f814
commit 41a4adb47b
23 changed files with 96 additions and 39 deletions

View file

@ -434,5 +434,6 @@
"terminal.ansiBrightMagenta": "#d778ff", "terminal.ansiBrightMagenta": "#d778ff",
"terminal.ansiBrightCyan": "#78ffff", "terminal.ansiBrightCyan": "#78ffff",
"terminal.ansiBrightWhite": "#ffffff" "terminal.ansiBrightWhite": "#ffffff"
} },
"semanticHighlighting": true
} }

View file

@ -18,5 +18,6 @@
"menu.foreground": "#CCCCCC", "menu.foreground": "#CCCCCC",
"statusBarItem.remoteForeground": "#FFF", "statusBarItem.remoteForeground": "#FFF",
"statusBarItem.remoteBackground": "#16825D" "statusBarItem.remoteBackground": "#16825D"
} },
"semanticHighlighting": true
} }

View file

@ -337,5 +337,6 @@
"foreground": "#569cd6" "foreground": "#569cd6"
} }
} }
] ],
"semanticHighlighting": true
} }

View file

@ -18,5 +18,6 @@
"settings.numberInputBorder": "#CECECE", "settings.numberInputBorder": "#CECECE",
"statusBarItem.remoteForeground": "#FFF", "statusBarItem.remoteForeground": "#FFF",
"statusBarItem.remoteBackground": "#16825D" "statusBarItem.remoteBackground": "#16825D"
} },
"semanticHighlighting": true
} }

View file

@ -394,5 +394,6 @@
"foreground": "#dc3958" "foreground": "#dc3958"
} }
} }
] ],
"semanticHighlighting": true
} }

View file

@ -572,5 +572,6 @@
"foreground": "#c7444a" "foreground": "#c7444a"
} }
} }
] ],
"semanticHighlighting": true
} }

View file

@ -476,5 +476,6 @@
"foreground": "#FD971F" "foreground": "#FD971F"
} }
} }
] ],
"semanticHighlighting": true
} }

View file

@ -494,5 +494,6 @@
"walkThrough.embeddedEditorBackground": "#00000014", "walkThrough.embeddedEditorBackground": "#00000014",
"editorIndentGuide.background": "#aaaaaa60", "editorIndentGuide.background": "#aaaaaa60",
"editorIndentGuide.activeBackground": "#777777b0" "editorIndentGuide.activeBackground": "#777777b0"
} },
"semanticHighlighting": true
} }

View file

@ -385,5 +385,6 @@
"foreground": "#ec0d1e" "foreground": "#ec0d1e"
} }
} }
] ],
"semanticHighlighting": true
} }

View file

@ -477,5 +477,6 @@
"terminal.ansiBrightMagenta": "#6c71c4", "terminal.ansiBrightMagenta": "#6c71c4",
"terminal.ansiBrightCyan": "#93a1a1", "terminal.ansiBrightCyan": "#93a1a1",
"terminal.ansiBrightWhite": "#fdf6e3" "terminal.ansiBrightWhite": "#fdf6e3"
} },
"semanticHighlighting": true
} }

View file

@ -484,5 +484,6 @@
// Interactive Playground // Interactive Playground
"walkThrough.embeddedEditorBackground": "#00000014" "walkThrough.embeddedEditorBackground": "#00000014"
} },
"semanticHighlighting": true
} }

View file

@ -255,5 +255,6 @@
"foreground": "#b267e6" "foreground": "#b267e6"
} }
} }
] ],
"semanticHighlighting": true
} }

View file

@ -466,15 +466,16 @@ class SemanticColoringFeature extends Disposable {
private _watchers: Record<string, ModelSemanticColoring>; private _watchers: Record<string, ModelSemanticColoring>;
private _semanticStyling: SemanticStyling; private _semanticStyling: SemanticStyling;
private _configurationService: IConfigurationService;
constructor(modelService: IModelService, themeService: IThemeService, configurationService: IConfigurationService, logService: ILogService) { constructor(modelService: IModelService, themeService: IThemeService, configurationService: IConfigurationService, logService: ILogService) {
super(); super();
this._configurationService = configurationService;
this._watchers = Object.create(null); this._watchers = Object.create(null);
this._semanticStyling = this._register(new SemanticStyling(themeService, logService)); this._semanticStyling = this._register(new SemanticStyling(themeService, logService));
const isSemanticColoringEnabled = (model: ITextModel) => { const isSemanticColoringEnabled = (model: ITextModel) => {
if (!themeService.getColorTheme().semanticHighlighting) {
return false;
}
const options = configurationService.getValue<IEditorSemanticHighlightingOptions>(SemanticColoringFeature.SETTING_ID, { overrideIdentifier: model.getLanguageIdentifier().language, resource: model.uri }); const options = configurationService.getValue<IEditorSemanticHighlightingOptions>(SemanticColoringFeature.SETTING_ID, { overrideIdentifier: model.getLanguageIdentifier().language, resource: model.uri });
return options && options.enabled; return options && options.enabled;
}; };
@ -485,6 +486,20 @@ class SemanticColoringFeature extends Disposable {
modelSemanticColoring.dispose(); modelSemanticColoring.dispose();
delete this._watchers[model.uri.toString()]; delete this._watchers[model.uri.toString()];
}; };
const handleSettingOrThemeChange = () => {
for (let model of modelService.getModels()) {
const curr = this._watchers[model.uri.toString()];
if (isSemanticColoringEnabled(model)) {
if (!curr) {
register(model);
}
} else {
if (curr) {
deregister(model, curr);
}
}
}
};
this._register(modelService.onModelAdded((model) => { this._register(modelService.onModelAdded((model) => {
if (isSemanticColoringEnabled(model)) { if (isSemanticColoringEnabled(model)) {
register(model); register(model);
@ -496,22 +511,12 @@ class SemanticColoringFeature extends Disposable {
deregister(model, curr); deregister(model, curr);
} }
})); }));
this._configurationService.onDidChangeConfiguration(e => { this._register(configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(SemanticColoringFeature.SETTING_ID)) { if (e.affectsConfiguration(SemanticColoringFeature.SETTING_ID)) {
for (let model of modelService.getModels()) { handleSettingOrThemeChange();
const curr = this._watchers[model.uri.toString()];
if (isSemanticColoringEnabled(model)) {
if (!curr) {
register(model);
}
} else {
if (curr) {
deregister(model, curr);
}
}
}
} }
}); }));
this._register(themeService.onDidColorThemeChange(handleSettingOrThemeChange));
} }
} }

View file

@ -138,6 +138,8 @@ class StandaloneTheme implements IStandaloneTheme {
public get tokenColorMap(): string[] { public get tokenColorMap(): string[] {
return []; return [];
} }
public readonly semanticHighlighting = false;
} }
function isBuiltinTheme(themeName: string): themeName is BuiltinTheme { function isBuiltinTheme(themeName: string): themeName is BuiltinTheme {

View file

@ -60,6 +60,8 @@ suite('TokenizationSupport2Adapter', () => {
return undefined; return undefined;
}, },
semanticHighlighting: false,
tokenColorMap: [] tokenColorMap: []
}; };
} }

View file

@ -112,6 +112,11 @@ export interface IColorTheme {
* List of all colors used with tokens. <code>getTokenStyleMetadata</code> references the colors by index into this list. * List of all colors used with tokens. <code>getTokenStyleMetadata</code> references the colors by index into this list.
*/ */
readonly tokenColorMap: string[]; readonly tokenColorMap: string[];
/**
* Defines whether semantic highlighting should be enabled for the theme.
*/
readonly semanticHighlighting: boolean;
} }
export interface IFileIconTheme { export interface IFileIconTheme {

View file

@ -28,6 +28,8 @@ export class TestColorTheme implements IColorTheme {
return undefined; return undefined;
} }
readonly semanticHighlighting = false;
get tokenColorMap(): string[] { get tokenColorMap(): string[] {
return []; return [];
} }

View file

@ -260,6 +260,9 @@ class InspectEditorTokensWidget extends Disposable implements IContentWidget {
} }
private _isSemanticColoringEnabled() { private _isSemanticColoringEnabled() {
if (!this._themeService.getColorTheme().semanticHighlighting) {
return false;
}
const options = this._configurationService.getValue<IEditorSemanticHighlightingOptions>('editor.semanticHighlighting', { overrideIdentifier: this._model.getLanguageIdentifier().language, resource: this._model.uri }); const options = this._configurationService.getValue<IEditorSemanticHighlightingOptions>('editor.semanticHighlighting', { overrideIdentifier: this._model.getLanguageIdentifier().language, resource: this._model.uri });
return options && options.enabled; return options && options.enabled;
} }

View file

@ -21,8 +21,8 @@ function getMockTheme(type: ThemeType): IColorTheme {
getColor: (colorId: ColorIdentifier): Color | undefined => themingRegistry.resolveDefaultColor(colorId, theme), getColor: (colorId: ColorIdentifier): Color | undefined => themingRegistry.resolveDefaultColor(colorId, theme),
defines: () => true, defines: () => true,
getTokenStyleMetadata: () => undefined, getTokenStyleMetadata: () => undefined,
tokenColorMap: [] tokenColorMap: [],
semanticHighlighting: false
}; };
return theme; return theme;
} }

View file

@ -59,6 +59,9 @@ export class ColorThemeData implements IWorkbenchColorTheme {
watch?: boolean; watch?: boolean;
extensionData?: ExtensionData; extensionData?: ExtensionData;
private themeSemanticHighlighting: boolean;
private customSemanticHighlightSupport: boolean | undefined;
private themeTokenColors: ITextMateThemingRule[] = []; private themeTokenColors: ITextMateThemingRule[] = [];
private customTokenColors: ITextMateThemingRule[] = []; private customTokenColors: ITextMateThemingRule[] = [];
private colorMap: IColorMap = {}; private colorMap: IColorMap = {};
@ -78,6 +81,12 @@ export class ColorThemeData implements IWorkbenchColorTheme {
this.label = label; this.label = label;
this.settingsId = settingsId; this.settingsId = settingsId;
this.isLoaded = false; this.isLoaded = false;
this.themeSemanticHighlighting = false;
this.customSemanticHighlightSupport = false;
}
get semanticHighlighting(): boolean {
return this.customSemanticHighlightSupport !== undefined ? this.customSemanticHighlightSupport : this.themeSemanticHighlighting;
} }
get tokenColors(): ITextMateThemingRule[] { get tokenColors(): ITextMateThemingRule[] {
@ -360,6 +369,7 @@ export class ColorThemeData implements IWorkbenchColorTheme {
public setCustomTokenColors(customTokenColors: ITokenColorCustomizations) { public setCustomTokenColors(customTokenColors: ITokenColorCustomizations) {
this.customTokenColors = []; this.customTokenColors = [];
this.customSemanticHighlightSupport = undefined;
// first add the non-theme specific settings // first add the non-theme specific settings
this.addCustomTokenColors(customTokenColors); this.addCustomTokenColors(customTokenColors);
@ -411,6 +421,9 @@ export class ColorThemeData implements IWorkbenchColorTheme {
} }
} }
} }
if (customTokenColors.semanticHighlighting !== undefined) {
this.customSemanticHighlightSupport = customTokenColors.semanticHighlighting;
}
} }
public ensureLoaded(extensionResourceLoaderService: IExtensionResourceLoaderService): Promise<void> { public ensureLoaded(extensionResourceLoaderService: IExtensionResourceLoaderService): Promise<void> {
@ -431,13 +444,15 @@ export class ColorThemeData implements IWorkbenchColorTheme {
const result = { const result = {
colors: {}, colors: {},
textMateRules: [], textMateRules: [],
stylingRules: undefined stylingRules: undefined,
semanticHighlighting: false
}; };
return _loadColorTheme(extensionResourceLoaderService, this.location, result).then(_ => { return _loadColorTheme(extensionResourceLoaderService, this.location, result).then(_ => {
this.isLoaded = true; this.isLoaded = true;
this.tokenStylingRules = result.stylingRules; this.tokenStylingRules = result.stylingRules;
this.colorMap = result.colors; this.colorMap = result.colors;
this.themeTokenColors = result.textMateRules; this.themeTokenColors = result.textMateRules;
this.themeSemanticHighlighting = result.semanticHighlighting;
}); });
} }
@ -562,7 +577,7 @@ function toCSSSelector(extensionId: string, path: string) {
return str; return str;
} }
function _loadColorTheme(extensionResourceLoaderService: IExtensionResourceLoaderService, themeLocation: URI, result: { textMateRules: ITextMateThemingRule[], colors: IColorMap, stylingRules: TokenStylingRule[] | undefined }): Promise<any> { function _loadColorTheme(extensionResourceLoaderService: IExtensionResourceLoaderService, themeLocation: URI, result: { textMateRules: ITextMateThemingRule[], colors: IColorMap, stylingRules: TokenStylingRule[] | undefined, semanticHighlighting: boolean }): Promise<any> {
if (resources.extname(themeLocation) === '.json') { if (resources.extname(themeLocation) === '.json') {
return extensionResourceLoaderService.readExtensionResource(themeLocation).then(content => { return extensionResourceLoaderService.readExtensionResource(themeLocation).then(content => {
let errors: Json.ParseError[] = []; let errors: Json.ParseError[] = [];
@ -581,6 +596,7 @@ function _loadColorTheme(extensionResourceLoaderService: IExtensionResourceLoade
convertSettings(contentValue.settings, result); convertSettings(contentValue.settings, result);
return null; return null;
} }
result.semanticHighlighting = result.semanticHighlighting || contentValue.semanticHighlighting;
let colors = contentValue.colors; let colors = contentValue.colors;
if (colors) { if (colors) {
if (typeof colors !== 'object') { if (typeof colors !== 'object') {
@ -605,10 +621,10 @@ function _loadColorTheme(extensionResourceLoaderService: IExtensionResourceLoade
return Promise.reject(new Error(nls.localize({ key: 'error.invalidformat.tokenColors', comment: ['{0} will be replaced by a path. Values in quotes should not be translated.'] }, "Problem parsing color theme file: {0}. Property 'tokenColors' should be either an array specifying colors or a path to a TextMate theme file", themeLocation.toString()))); return Promise.reject(new Error(nls.localize({ key: 'error.invalidformat.tokenColors', comment: ['{0} will be replaced by a path. Values in quotes should not be translated.'] }, "Problem parsing color theme file: {0}. Property 'tokenColors' should be either an array specifying colors or a path to a TextMate theme file", themeLocation.toString())));
} }
} }
let tokenStylingRules = contentValue.tokenStylingRules; // let tokenStylingRules = contentValue.tokenStylingRules;
if (tokenStylingRules && typeof tokenStylingRules === 'object') { // if (tokenStylingRules && typeof tokenStylingRules === 'object') {
result.stylingRules = readCustomTokenStyleRules(tokenStylingRules, result.stylingRules); // result.stylingRules = readCustomTokenStyleRules(tokenStylingRules, result.stylingRules);
} // }
return null; return null;
}); });
}); });

View file

@ -222,6 +222,10 @@ const colorThemeSchema: IJSONSchema = {
$ref: textmateColorsSchemaId $ref: textmateColorsSchemaId
} }
] ]
},
semanticHighlighting: {
type: 'boolean',
description: nls.localize('schema.supportsSemanticHighlighting', 'Whether semantic highlighting should be enabled for this theme.')
} }
} }
}; };

View file

@ -132,6 +132,10 @@ const tokenColorSchema: IJSONSchema = {
textMateRules: { textMateRules: {
description: nls.localize('editorColors.textMateRules', 'Sets colors and styles using textmate theming rules (advanced).'), description: nls.localize('editorColors.textMateRules', 'Sets colors and styles using textmate theming rules (advanced).'),
$ref: textmateColorsSchemaId $ref: textmateColorsSchemaId
},
semanticHighlighting: {
description: nls.localize('editorColors.semanticHighlighting', 'Whether semantic highlighting should be enabled for this theme.'),
type: 'boolean'
} }
} }
}; };
@ -154,6 +158,7 @@ const tokenColorCustomizationConfiguration: IConfigurationNode = {
[ThemeSettings.TOKEN_COLOR_CUSTOMIZATIONS_EXPERIMENTAL]: experimentalTokenStylingCustomizationSchema [ThemeSettings.TOKEN_COLOR_CUSTOMIZATIONS_EXPERIMENTAL]: experimentalTokenStylingCustomizationSchema
} }
}; };
configurationRegistry.registerConfiguration(tokenColorCustomizationConfiguration); configurationRegistry.registerConfiguration(tokenColorCustomizationConfiguration);
export function updateColorThemeConfigurationSchemas(themes: IWorkbenchColorTheme[]) { export function updateColorThemeConfigurationSchemas(themes: IWorkbenchColorTheme[]) {

View file

@ -97,7 +97,7 @@ export interface IColorCustomizations {
} }
export interface ITokenColorCustomizations { export interface ITokenColorCustomizations {
[groupIdOrThemeSettingsId: string]: string | ITokenColorizationSetting | ITokenColorCustomizations | undefined | ITextMateThemingRule[]; [groupIdOrThemeSettingsId: string]: string | ITokenColorizationSetting | ITokenColorCustomizations | undefined | ITextMateThemingRule[] | boolean;
comments?: string | ITokenColorizationSetting; comments?: string | ITokenColorizationSetting;
strings?: string | ITokenColorizationSetting; strings?: string | ITokenColorizationSetting;
numbers?: string | ITokenColorizationSetting; numbers?: string | ITokenColorizationSetting;
@ -106,6 +106,7 @@ export interface ITokenColorCustomizations {
functions?: string | ITokenColorizationSetting; functions?: string | ITokenColorizationSetting;
variables?: string | ITokenColorizationSetting; variables?: string | ITokenColorizationSetting;
textMateRules?: ITextMateThemingRule[]; textMateRules?: ITextMateThemingRule[];
semanticHighlighting?: boolean;
} }
export interface IExperimentalTokenStyleCustomizations { export interface IExperimentalTokenStyleCustomizations {