fix score based rule matching

This commit is contained in:
Martin Aeschlimann
2019-09-19 16:11:43 +02:00
parent 4a1614f80b
commit 6dce52093c
4 changed files with 39 additions and 44 deletions
@@ -1,12 +1,6 @@
{
"name": "Abyss",
"tokenColors": [
{
"settings": {
"background": "#000c18",
"foreground": "#6688cc"
}
},
{
"scope": ["meta.embedded", "source.groovy.embedded"],
"settings": {
@@ -260,6 +254,9 @@
],
"colors": {
"editor.background": "#000c18",
"editor.foreground": "#6688cc",
// Base
// "foreground": "",
"focusBorder": "#596F99",
@@ -303,8 +300,6 @@
"scrollbarSlider.hoverBackground": "#3B3F5188",
// Editor
"editor.background": "#000c18",
// "editor.foreground": "#6688cc",
"editorWidget.background": "#262641",
"editorCursor.foreground": "#ddbb88",
"editorWhitespace.foreground": "#103050",
@@ -71,7 +71,7 @@ export namespace TokenStyle {
}
}
export type ProbeScope = string[] | string;
export type ProbeScope = string[];
export interface TokenStyleFunction {
(theme: ITheme): TokenStyle | undefined;
@@ -246,13 +246,13 @@ export function getTokenStyleRegistry(): ITokenStyleRegistry {
// colors
export const comments = registerTokenStyle('comments', { scopesToProbe: ['comment'], dark: null, light: null, hc: null }, nls.localize('comments', "Token style for comments."));
export const strings = registerTokenStyle('strings', { scopesToProbe: ['string'], dark: null, light: null, hc: null }, nls.localize('strings', "Token style for strings."));
export const keywords = registerTokenStyle('keywords', { scopesToProbe: ['keyword.control', 'storage', 'storage.type'], dark: null, light: null, hc: null }, nls.localize('keywords', "Token style for keywords."));
export const numbers = registerTokenStyle('numbers', { scopesToProbe: ['constant.numeric'], dark: null, light: null, hc: null }, nls.localize('numbers', "Token style for numbers."));
export const types = registerTokenStyle('types', { scopesToProbe: ['entity.name.type', 'entity.name.class', 'support.type', 'support.class'], dark: null, light: null, hc: null }, nls.localize('types', "Token style for types."));
export const functions = registerTokenStyle('functions', { scopesToProbe: ['entity.name.function', 'support.function'], dark: null, light: null, hc: null }, nls.localize('functions', "Token style for functions."));
export const variables = registerTokenStyle('variables', { scopesToProbe: ['variable', 'entity.name.variable'], dark: null, light: null, hc: null }, nls.localize('variables', "Token style for variables."));
export const comments = registerTokenStyle('comments', { scopesToProbe: [['comment']], dark: null, light: null, hc: null }, nls.localize('comments', "Token style for comments."));
export const strings = registerTokenStyle('strings', { scopesToProbe: [['string']], dark: null, light: null, hc: null }, nls.localize('strings', "Token style for strings."));
export const keywords = registerTokenStyle('keywords', { scopesToProbe: [['keyword.control'], ['storage'], ['storage.type']], dark: null, light: null, hc: null }, nls.localize('keywords', "Token style for keywords."));
export const numbers = registerTokenStyle('numbers', { scopesToProbe: [['constant.numeric']], dark: null, light: null, hc: null }, nls.localize('numbers', "Token style for numbers."));
export const types = registerTokenStyle('types', { scopesToProbe: [['entity.name.type'], ['entity.name.class'], ['support.type'], ['support.class']], dark: null, light: null, hc: null }, nls.localize('types', "Token style for types."));
export const functions = registerTokenStyle('functions', { scopesToProbe: [['entity.name.function'], ['support.function']], dark: null, light: null, hc: null }, nls.localize('functions', "Token style for functions."));
export const variables = registerTokenStyle('variables', { scopesToProbe: [['variable'], ['entity.name.variable']], dark: null, light: null, hc: null }, nls.localize('variables', "Token style for variables."));
/**
* @param colorValue Resolve a color value in the context of a theme
@@ -138,7 +138,9 @@ export class ColorThemeData implements IColorTheme {
/** Public for testing reasons */
public findTokenStyleForScope(scope: ProbeScope): TokenStyle | undefined {
let foreground: string | null = null;
let foregroundColor = this.getColor(editorForeground);
let foreground = foregroundColor ? foregroundColor.toString() : null;
let fontStyle: string | null = null;
let foregroundScore = -1;
let fontStyleScore = -1;
@@ -154,12 +156,15 @@ export class ColorThemeData implements IColorTheme {
scopeMatchers[i] = matcher = getScopeMatcher(tokenColors[i]);
}
const score = matcher(scope);
if (score > foregroundScore && settings.foreground) {
foreground = settings.foreground;
}
if (score > fontStyleScore && types.isString(settings.fontStyle)) {
fontStyle = settings.fontStyle;
if (score >= 0) {
if (score >= foregroundScore && settings.foreground) {
foreground = settings.foreground;
}
if (score >= fontStyleScore && types.isString(settings.fontStyle)) {
fontStyle = settings.fontStyle;
}
}
}
}
@@ -173,10 +178,7 @@ export class ColorThemeData implements IColorTheme {
}
findTokenStyleForScopeInScopes(this.customTokenScopeMatchers, this.customTokenColors);
if (foreground !== null || fontStyle !== null) {
return getTokenStyle(foreground, fontStyle);
}
return undefined;
return getTokenStyle(foreground, fontStyle);
}
@@ -464,26 +466,19 @@ const noMatch = (_scope: ProbeScope) => -1;
function nameMatcher(identifers: string[], scope: ProbeScope): number {
function findInIdents(s: string, lastIndent: number): number {
for (let i = lastIndent - 1; i >= 0; i--) {
if (scopesAreMatching(identifers[i], s)) {
if (scopesAreMatching(s, identifers[i])) {
return i;
}
}
return -1;
}
if (!Array.isArray(scope)) {
const idx = findInIdents(scope, identifers.length);
if (idx >= 0) {
return idx * 0x10000 + scope.length;
}
return -1;
}
if (scope.length < identifers.length) {
return -1;
}
let lastScopeIndex = scope.length - 1;
let lastIdentifierIndex = findInIdents(scope[lastScopeIndex--], identifers.length);
if (lastIdentifierIndex >= 0) {
const score = lastIdentifierIndex * 0x10000 + scope.length;
const score = (lastIdentifierIndex + 1) * 0x10000 + scope.length;
while (lastScopeIndex >= 0) {
lastIdentifierIndex = findInIdents(scope[lastScopeIndex--], lastIdentifierIndex);
if (lastIdentifierIndex === -1) {
@@ -520,10 +515,13 @@ function getScopeMatcher(rule: ITokenColorizationRule): Matcher<ProbeScope> {
} else {
matchers.push(...createMatchers(ruleScope, nameMatcher));
}
if (matchers.length === 0) {
return noMatch;
}
return (scope: ProbeScope) => {
let max = 0;
for (const m of matchers) {
max = Math.max(max, m.matcher(scope));
let max = matchers[0].matcher(scope);
for (let i = 1; i < matchers.length; i++) {
max = Math.max(max, matchers[i].matcher(scope));
}
return max;
};
@@ -15,6 +15,7 @@ import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemPro
import { Schemas } from 'vs/base/common/network';
import { URI } from 'vs/base/common/uri';
import { getPathFromAmdModule } from 'vs/base/common/amd';
import { editorForeground } from 'vs/platform/theme/common/colorRegistry';
function ts(foreground: string | undefined, styleFlags: number | undefined): TokenStyle {
const foregroundColor = isString(foreground) ? Color.fromHex(foreground) : undefined;
@@ -154,12 +155,12 @@ suite('Themes - TokenStyleResolving', () => {
assertTokenStyles(themeData, {
[comments]: ts('#384887', 0),
[variables]: ts('#9966b8', 0),
[types]: ts('#f06431', 0),
[functions]: ts('#8ab1b0', 0),
[variables]: ts('#6688cc', 0),
[types]: ts('#ffeebb', TokenStyleBits.UNDERLINE),
[functions]: ts('#ddbb88', 0),
[strings]: ts('#22aa44', 0),
[numbers]: ts('#f280d0', 0),
[keywords]: ts('#98676a', 0)
[keywords]: ts('#225588', 0)
});
});
@@ -209,6 +210,7 @@ suite('Themes - TokenStyleResolving', () => {
themeData.setCustomTokenColors(customTokenColors);
let tokenStyle;
let defaultTokenStyle = new TokenStyle(themeData.getColor(editorForeground));
tokenStyle = themeData.findTokenStyleForScope(['variable']);
assertTokenStyle(tokenStyle, ts('#F8F8F2', 0), 'variable');
@@ -217,13 +219,13 @@ suite('Themes - TokenStyleResolving', () => {
assertTokenStyle(tokenStyle, ts('#F92672', TokenStyleBits.ITALIC | TokenStyleBits.BOLD | TokenStyleBits.UNDERLINE), 'keyword');
tokenStyle = themeData.findTokenStyleForScope(['keyword']);
assertTokenStyle(tokenStyle, undefined, 'keyword');
assertTokenStyle(tokenStyle, defaultTokenStyle, 'keyword');
tokenStyle = themeData.findTokenStyleForScope(['keyword.operator']);
assertTokenStyle(tokenStyle, ts('#F92672', TokenStyleBits.ITALIC | TokenStyleBits.BOLD | TokenStyleBits.UNDERLINE), 'keyword.operator');
tokenStyle = themeData.findTokenStyleForScope(['keyword.operators']);
assertTokenStyle(tokenStyle, undefined, 'keyword.operators');
assertTokenStyle(tokenStyle, defaultTokenStyle, 'keyword.operators');
tokenStyle = themeData.findTokenStyleForScope(['storage']);
assertTokenStyle(tokenStyle, ts('#F92672', TokenStyleBits.ITALIC), 'storage');