[clang-tools-extra] r368136 - [clangd] Added a TextMate theme parser to the vscode extension.
Johan Vikstrom via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 7 01:48:52 PDT 2019
Author: jvikstrom
Date: Wed Aug 7 01:48:52 2019
New Revision: 368136
URL: http://llvm.org/viewvc/llvm-project?rev=368136&view=rev
Log:
[clangd] Added a TextMate theme parser to the vscode extension.
Summary:
Adds a TextMate parser module to the vscode extension. It parses a theme into an array of a pair of TextMate scopes and text colors.
Reviewers: hokein, ilya-biryukov
Subscribers: MaskRay, jkorous, arphaman, kadircet, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D65738
Added:
clang-tools-extra/trunk/clangd/clients/clangd-vscode/src/semantic-highlighting.ts
clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/assets/
clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/assets/includeTheme.jsonc
clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/assets/simpleTheme.jsonc
clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts
Modified:
clang-tools-extra/trunk/clangd/clients/clangd-vscode/package.json
Modified: clang-tools-extra/trunk/clangd/clients/clangd-vscode/package.json
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/clients/clangd-vscode/package.json?rev=368136&r1=368135&r2=368136&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/clients/clangd-vscode/package.json (original)
+++ clang-tools-extra/trunk/clangd/clients/clangd-vscode/package.json Wed Aug 7 01:48:52 2019
@@ -36,14 +36,15 @@
"test": "node ./node_modules/vscode/bin/test"
},
"dependencies": {
+ "jsonc-parser": "^2.1.0",
"vscode-languageclient": "^5.3.0-next.6",
"vscode-languageserver": "^5.3.0-next.6"
},
"devDependencies": {
"@types/mocha": "^2.2.32",
"@types/node": "^6.0.40",
- "mocha": "^5.2.0",
"clang-format": "1.2.4",
+ "mocha": "^5.2.0",
"typescript": "^2.0.3",
"vscode": "^1.1.0"
},
Added: clang-tools-extra/trunk/clangd/clients/clangd-vscode/src/semantic-highlighting.ts
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/clients/clangd-vscode/src/semantic-highlighting.ts?rev=368136&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/clients/clangd-vscode/src/semantic-highlighting.ts (added)
+++ clang-tools-extra/trunk/clangd/clients/clangd-vscode/src/semantic-highlighting.ts Wed Aug 7 01:48:52 2019
@@ -0,0 +1,102 @@
+import * as fs from 'fs';
+import * as jsonc from "jsonc-parser";
+import * as path from 'path';
+import * as vscode from 'vscode';
+
+// A rule for how to color TextMate scopes.
+interface TokenColorRule {
+ // A TextMate scope that specifies the context of the token, e.g.
+ // "entity.name.function.cpp".
+ scope: string;
+ // foreground is the color tokens of this scope should have.
+ foreground: string;
+}
+
+// Get all token color rules provided by the theme.
+function loadTheme(themeName: string): Promise<TokenColorRule[]> {
+ const extension =
+ vscode.extensions.all.find((extension: vscode.Extension<any>) => {
+ const contribs = extension.packageJSON.contributes;
+ if (!contribs || !contribs.themes)
+ return false;
+ return contribs.themes.some((theme: any) => theme.id === themeName ||
+ theme.label === themeName);
+ });
+
+ if (!extension) {
+ return Promise.reject('Could not find a theme with name: ' + themeName);
+ }
+
+ const themeInfo = extension.packageJSON.contributes.themes.find(
+ (theme: any) => theme.id === themeName || theme.label === themeName);
+ return parseThemeFile(path.join(extension.extensionPath, themeInfo.path));
+}
+
+/**
+ * Parse the TextMate theme at fullPath. If there are multiple TextMate scopes
+ * of the same name in the include chain only the earliest entry of the scope is
+ * saved.
+ * @param fullPath The absolute path to the theme.
+ * @param seenScopes A set containing the name of the scopes that have already
+ * been set.
+ */
+export async function parseThemeFile(
+ fullPath: string, seenScopes?: Set<string>): Promise<TokenColorRule[]> {
+ if (!seenScopes)
+ seenScopes = new Set();
+ // FIXME: Add support for themes written as .tmTheme.
+ if (path.extname(fullPath) === '.tmTheme')
+ return [];
+ try {
+ const contents = await readFileText(fullPath);
+ const parsed = jsonc.parse(contents);
+ const rules: TokenColorRule[] = [];
+ // To make sure it does not crash if tokenColors is undefined.
+ if (!parsed.tokenColors)
+ parsed.tokenColors = [];
+ parsed.tokenColors.forEach((rule: any) => {
+ if (!rule.scope || !rule.settings || !rule.settings.foreground)
+ return;
+ const textColor = rule.settings.foreground;
+ // Scopes that were found further up the TextMate chain should not be
+ // overwritten.
+ const addColor = (scope: string) => {
+ if (seenScopes.has(scope))
+ return;
+ rules.push({scope, foreground : textColor});
+ seenScopes.add(scope);
+ };
+ if (rule.scope instanceof Array) {
+ return rule.scope.forEach((s: string) => addColor(s));
+ }
+ addColor(rule.scope);
+ });
+
+ if (parsed.include)
+ // Get all includes and merge into a flat list of parsed json.
+ return [
+ ...(await parseThemeFile(
+ path.join(path.dirname(fullPath), parsed.include), seenScopes)),
+ ...rules
+ ];
+ return rules;
+ } catch (err) {
+ // If there is an error opening a file, the TextMate files that were
+ // correctly found and parsed further up the chain should be returned.
+ // Otherwise there will be no highlightings at all.
+ console.warn('Could not open file: ' + fullPath + ', error: ', err);
+ }
+
+ return [];
+}
+
+function readFileText(path: string): Promise<string> {
+ return new Promise((resolve, reject) => {
+ fs.readFile(path, 'utf8', (err, data) => {
+ if (err) {
+ return reject(err);
+ }
+ return resolve(data);
+ });
+ });
+}
Added: clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/assets/includeTheme.jsonc
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/assets/includeTheme.jsonc?rev=368136&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/assets/includeTheme.jsonc (added)
+++ clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/assets/includeTheme.jsonc Wed Aug 7 01:48:52 2019
@@ -0,0 +1,28 @@
+{
+ // Some comment
+ "include": "simpleTheme.jsonc",
+ "name": "TestTheme",
+ "type": "dark",
+ "colors": {
+ "dropdown.background": "#fff"
+ },
+ "tokenColors": [
+ {
+ "settings": {
+ "foreground": "#fff"
+ }
+ },
+ {
+ "scope": "a",
+ "settings": {
+ "foreground": "#fff"
+ }
+ },
+ {
+ "scope": ["a", "b"],
+ "settings": {
+ "foreground": "#000"
+ }
+ }
+ ]
+}
Added: clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/assets/simpleTheme.jsonc
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/assets/simpleTheme.jsonc?rev=368136&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/assets/simpleTheme.jsonc (added)
+++ clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/assets/simpleTheme.jsonc Wed Aug 7 01:48:52 2019
@@ -0,0 +1,17 @@
+{
+ // Some comment
+ "tokenColors": [
+ {
+ "scope": "a",
+ "settings": {
+ "foreground": "#ff0000"
+ }
+ },
+ {
+ "scope": "c",
+ "settings": {
+ "foreground": "#bcd"
+ }
+ }
+ ]
+}
Added: clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts?rev=368136&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts (added)
+++ clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts Wed Aug 7 01:48:52 2019
@@ -0,0 +1,18 @@
+import * as assert from 'assert';
+import * as path from 'path';
+
+import * as TM from '../src/semantic-highlighting';
+
+suite('TextMate Tests', () => {
+ test('Parses arrays of textmate themes.', async () => {
+ const themePath =
+ path.join(__dirname, '../../test/assets/includeTheme.jsonc');
+ const scopeColorRules = await TM.parseThemeFile(themePath);
+ const getScopeRule = (scope: string) =>
+ scopeColorRules.find((v) => v.scope === scope);
+ assert.equal(scopeColorRules.length, 3);
+ assert.deepEqual(getScopeRule('a'), {scope : 'a', textColor : '#fff'});
+ assert.deepEqual(getScopeRule('b'), {scope : 'b', textColor : '#000'});
+ assert.deepEqual(getScopeRule('c'), {scope : 'c', textColor : '#bcd'});
+ });
+});
More information about the cfe-commits
mailing list