jvikstrom updated this revision to Diff 213568.
jvikstrom added a comment.

Clarified comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D65738/new/

https://reviews.llvm.org/D65738

Files:
  clang-tools-extra/clangd/clients/clangd-vscode/package.json
  clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts
  
clang-tools-extra/clangd/clients/clangd-vscode/test/assets/firstIncludedTheme.jsonc
  
clang-tools-extra/clangd/clients/clangd-vscode/test/assets/secondIncludedTheme.jsonc
  clang-tools-extra/clangd/clients/clangd-vscode/test/assets/testTheme.jsonc
  
clang-tools-extra/clangd/clients/clangd-vscode/test/assets/tmThemeInclude.tmTheme
  
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
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts
@@ -0,0 +1,17 @@
+/** The module 'assert' provides assertion methods from node */
+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/testTheme.jsonc');
+    const scopeColorRules = await TM.parseThemeFile(themePath);
+    const getScopeRule = (scope: string) =>
+        scopeColorRules.find((v) => v.scope === scope);
+    assert.equal(scopeColorRules.length, 2);
+    assert.deepEqual(getScopeRule('a'), {scope : 'a', textColor : '#fff'});
+    assert.deepEqual(getScopeRule('b'), {scope : 'b', textColor : '#000'});
+  });
+});
\ No newline at end of file
Index: clang-tools-extra/clangd/clients/clangd-vscode/test/assets/tmThemeInclude.tmTheme
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/clients/clangd-vscode/test/assets/tmThemeInclude.tmTheme
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd";>
+<plist version="1.0">
+<dict>
+</dict>
Index: clang-tools-extra/clangd/clients/clangd-vscode/test/assets/testTheme.jsonc
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/clients/clangd-vscode/test/assets/testTheme.jsonc
@@ -0,0 +1,16 @@
+{
+    // Some comment
+    "include": "firstIncludedTheme.jsonc",
+    "name": "TestTheme",
+    "type": "dark",
+    "colors": {
+        "dropdown.background": "#fff"
+    },
+    "tokenColors": [
+        {
+            "settings": {
+                "foreground": "#fff"
+            }
+        }
+    ]
+}
Index: clang-tools-extra/clangd/clients/clangd-vscode/test/assets/secondIncludedTheme.jsonc
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/clients/clangd-vscode/test/assets/secondIncludedTheme.jsonc
@@ -0,0 +1,11 @@
+{
+    "include": "tmThemeInclude.tmTheme",
+    "tokenColors": [
+        {
+            "scope": "a",
+            "settings": {
+                "foreground": "#ff0000"
+            }
+        }
+    ]
+}
Index: clang-tools-extra/clangd/clients/clangd-vscode/test/assets/firstIncludedTheme.jsonc
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/clients/clangd-vscode/test/assets/firstIncludedTheme.jsonc
@@ -0,0 +1,18 @@
+{
+    // Some comment
+    "include": "secondIncludedTheme.jsonc",
+    "tokenColors": [
+        {
+            "scope": "a",
+            "settings": {
+                "foreground": "#fff"
+            }
+        },
+        {
+            "scope": ["a", "b"],
+            "settings": {
+                "foreground": "#000"
+            }
+        }
+    ]
+}
Index: clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts
@@ -0,0 +1,97 @@
+import * as fs from 'fs';
+import * as jsonc from "jsonc-parser";
+import * as path from 'path';
+import * as vscode from 'vscode';
+
+interface TokenColorRule {
+  scope: string, textColor: string,
+}
+
+// Gets a TextMate theme and all its included themes by its name.
+async 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 extensionInfo = extension.packageJSON.contributes.themes.find(
+      (theme: any) => theme.id === themeName || theme.label === themeName);
+  return parseThemeFile(path.join(extension.extensionPath, extensionInfo.path));
+}
+
+/**
+ * Recursively parse the TM grammar at fullPath. If there are multiple TM 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 scopeSet A set containing the name of the scopes that have already
+ *     been set.
+ */
+export async function parseThemeFile(fullPath: string, scopeSet?: Set<string>):
+    Promise<TokenColorRule[]> {
+  if (!scopeSet)
+    scopeSet = new Set();
+  // FIXME: Add support for themes written as .thTheme.
+  if (path.extname(fullPath) === '.tmTheme')
+    return [];
+  // If there is an error opening a file, the TM files that were correctly found
+  // and parsed further up the chain should be returned. Otherwise there will be
+  // no highlightings at all.
+  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 TM chain should not be
+      // overwritten.
+      const addColor = (scope: string) => {
+        if (scopeSet.has(scope))
+          return;
+        rules.push({scope, textColor});
+        scopeSet.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), scopeSet)),
+        ...rules
+      ];
+    return rules;
+  } catch (err) {
+    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);
+      }
+      resolve(data);
+    });
+  });
+}
Index: clang-tools-extra/clangd/clients/clangd-vscode/package.json
===================================================================
--- clang-tools-extra/clangd/clients/clangd-vscode/package.json
+++ clang-tools-extra/clangd/clients/clangd-vscode/package.json
@@ -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"
     },
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to