jvikstrom updated this revision to Diff 214774. jvikstrom added a comment. Rebased into master.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D65856/new/ https://reviews.llvm.org/D65856 Files: clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts Index: clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts =================================================================== --- clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts +++ clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts @@ -35,4 +35,19 @@ testCases.forEach((testCase, i) => assert.deepEqual( TM.decodeTokens(testCase), expected[i])); }); + test('ScopeRules overrides for more specific themes', () => { + const scopes = [ 'a.b.c.d', 'a.b.f', 'a' ]; + const rules = [ + {scope : 'a.b.c', foreground : '1'}, + {scope : 'a.b', foreground : '2'}, + {scope : 'a.b.c.d', foreground : '3'}, + {scope : 'a', foreground : '4'}, + ]; + + const tm = new TM.ScopeRules(scopes); + rules.forEach((r) => tm.addRule(r)); + assert.deepEqual(tm.getRule(0), rules[2]); + assert.deepEqual(tm.getRule(1), rules[1]); + assert.deepEqual(tm.getRule(2), rules[3]); + }); }); Index: clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts =================================================================== --- clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts +++ clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts @@ -101,6 +101,39 @@ foreground: string; } +export class ScopeRules { + // The TextMate scopes that should be mapped to a color. + private scopes: string[]; + // Contains the current best matching scope for the scope at the corresponding + // index. + private scopeRules: TokenColorRule[]; + + constructor(scopes: string[]) { + this.scopes = scopes; + this.scopeRules = + this.scopes.map(() => ({scope : '', foreground : '#000'})); + } + + addRule(rule: TokenColorRule) { + // Find the associated clangd scope(s) index for this scope. A scope being a + // possible candidate means that the clangd scope must have the rule's scope + // as a prefix. + const allCandidates = + this.scopes.map((s, i) => ({s : s, i : i})) + .filter(({s}) => s.substr(0, rule.scope.length) === rule.scope); + // If this scope is more specific than any of current scopes for the clangd + // scopes it should be replaced. As both options are prefixes of the clangd + // scope it's enough to compare lengths. + allCandidates.forEach(({i}) => { + if (rule.scope.length > this.scopeRules[i].scope.length) { + this.scopeRules[i] = rule; + } + }); + } + + getRule(idx: number) { return this.scopeRules[idx]; } +} + // Get all token color rules provided by the theme. function loadTheme(themeName: string): Promise<TokenColorRule[]> { const extension =
Index: clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts =================================================================== --- clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts +++ clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts @@ -35,4 +35,19 @@ testCases.forEach((testCase, i) => assert.deepEqual( TM.decodeTokens(testCase), expected[i])); }); + test('ScopeRules overrides for more specific themes', () => { + const scopes = [ 'a.b.c.d', 'a.b.f', 'a' ]; + const rules = [ + {scope : 'a.b.c', foreground : '1'}, + {scope : 'a.b', foreground : '2'}, + {scope : 'a.b.c.d', foreground : '3'}, + {scope : 'a', foreground : '4'}, + ]; + + const tm = new TM.ScopeRules(scopes); + rules.forEach((r) => tm.addRule(r)); + assert.deepEqual(tm.getRule(0), rules[2]); + assert.deepEqual(tm.getRule(1), rules[1]); + assert.deepEqual(tm.getRule(2), rules[3]); + }); }); Index: clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts =================================================================== --- clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts +++ clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts @@ -101,6 +101,39 @@ foreground: string; } +export class ScopeRules { + // The TextMate scopes that should be mapped to a color. + private scopes: string[]; + // Contains the current best matching scope for the scope at the corresponding + // index. + private scopeRules: TokenColorRule[]; + + constructor(scopes: string[]) { + this.scopes = scopes; + this.scopeRules = + this.scopes.map(() => ({scope : '', foreground : '#000'})); + } + + addRule(rule: TokenColorRule) { + // Find the associated clangd scope(s) index for this scope. A scope being a + // possible candidate means that the clangd scope must have the rule's scope + // as a prefix. + const allCandidates = + this.scopes.map((s, i) => ({s : s, i : i})) + .filter(({s}) => s.substr(0, rule.scope.length) === rule.scope); + // If this scope is more specific than any of current scopes for the clangd + // scopes it should be replaced. As both options are prefixes of the clangd + // scope it's enough to compare lengths. + allCandidates.forEach(({i}) => { + if (rule.scope.length > this.scopeRules[i].scope.length) { + this.scopeRules[i] = rule; + } + }); + } + + getRule(idx: number) { return this.scopeRules[idx]; } +} + // Get all token color rules provided by the theme. function loadTheme(themeName: string): Promise<TokenColorRule[]> { const extension =
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits