|
1 | 1 | import { ConfigurationTarget, workspace } from "vscode";
|
| 2 | +import util = require("util"); |
| 3 | +import { IEquatable, ValueEqualsSet } from "./utilities/hashset"; |
2 | 4 |
|
3 |
| -export type TextMateRule = { scope: string | string[]; settings: { fontStyle?: string; foreground?: string } }; |
4 |
| -type TextMateRules = { textMateRules: TextMateRule[] }; |
| 5 | +export class TextMateRule implements IEquatable<TextMateRule> { |
| 6 | + public scope: string | string[]; |
| 7 | + public settings: { fontStyle?: string; foreground?: string }; |
5 | 8 |
|
6 |
| -const customFontStyleRules: TextMateRule[] = [ |
7 |
| - { scope: "renpy.meta.plain", settings: { fontStyle: "" } }, |
8 |
| - { scope: "renpy.meta.i", settings: { fontStyle: "italic" } }, |
9 |
| - { scope: "renpy.meta.b", settings: { fontStyle: "bold" } }, |
10 |
| - { scope: ["renpy.meta.u", "renpy.meta.a"], settings: { fontStyle: "underline" } }, |
11 |
| - { scope: "renpy.meta.s", settings: { fontStyle: "strikethrough" } }, |
| 9 | + constructor(scope: string | string[], settings: { fontStyle?: string; foreground?: string }) { |
| 10 | + this.scope = scope; |
| 11 | + this.settings = settings; |
| 12 | + } |
| 13 | + |
| 14 | + equals(other: TextMateRule): boolean { |
| 15 | + return util.isDeepStrictEqual(this, other); |
| 16 | + } |
| 17 | +} |
| 18 | +type TextMateRuleConfiguration = { scope: string | string[]; settings: { fontStyle?: string; foreground?: string } }; |
| 19 | +type TextMateRules = { textMateRules: TextMateRuleConfiguration[] }; |
| 20 | + |
| 21 | +const customFontStyleRules = new ValueEqualsSet<TextMateRule>([ |
| 22 | + new TextMateRule("renpy.meta.plain", { fontStyle: "" }), |
| 23 | + new TextMateRule("renpy.meta.i", { fontStyle: "italic" }), |
| 24 | + new TextMateRule("renpy.meta.b", { fontStyle: "bold" }), |
| 25 | + new TextMateRule(["renpy.meta.u", "renpy.meta.a"], { fontStyle: "underline" }), |
| 26 | + new TextMateRule("renpy.meta.s", { fontStyle: "strikethrough" }), |
12 | 27 |
|
13 |
| - { scope: "renpy.meta.i renpy.meta.b", settings: { fontStyle: "italic bold" } }, |
14 |
| - { scope: "renpy.meta.i renpy.meta.u", settings: { fontStyle: "italic underline" } }, |
15 |
| - { scope: "renpy.meta.i renpy.meta.s", settings: { fontStyle: "italic strikethrough" } }, |
16 |
| - { scope: "renpy.meta.b renpy.meta.u", settings: { fontStyle: "bold underline" } }, |
17 |
| - { scope: "renpy.meta.b renpy.meta.s", settings: { fontStyle: "bold strikethrough" } }, |
18 |
| - { scope: "renpy.meta.u renpy.meta.s", settings: { fontStyle: "underline strikethrough" } }, |
| 28 | + new TextMateRule("renpy.meta.i renpy.meta.b", { fontStyle: "italic bold" }), |
| 29 | + new TextMateRule("renpy.meta.i renpy.meta.u", { fontStyle: "italic underline" }), |
| 30 | + new TextMateRule("renpy.meta.i renpy.meta.s", { fontStyle: "italic strikethrough" }), |
| 31 | + new TextMateRule("renpy.meta.b renpy.meta.u", { fontStyle: "bold underline" }), |
| 32 | + new TextMateRule("renpy.meta.b renpy.meta.s", { fontStyle: "bold strikethrough" }), |
| 33 | + new TextMateRule("renpy.meta.u renpy.meta.s", { fontStyle: "underline strikethrough" }), |
19 | 34 |
|
20 |
| - { scope: "renpy.meta.i renpy.meta.b renpy.meta.u", settings: { fontStyle: "italic bold underline" } }, |
21 |
| - { scope: "renpy.meta.i renpy.meta.b renpy.meta.s", settings: { fontStyle: "italic bold strikethrough" } }, |
22 |
| - { scope: "renpy.meta.i renpy.meta.u renpy.meta.s", settings: { fontStyle: "italic underline strikethrough" } }, |
23 |
| - { scope: "renpy.meta.b renpy.meta.u renpy.meta.s", settings: { fontStyle: "bold underline strikethrough" } }, |
| 35 | + new TextMateRule("renpy.meta.i renpy.meta.b renpy.meta.u", { fontStyle: "italic bold underline" }), |
| 36 | + new TextMateRule("renpy.meta.i renpy.meta.b renpy.meta.s", { fontStyle: "italic bold strikethrough" }), |
| 37 | + new TextMateRule("renpy.meta.i renpy.meta.u renpy.meta.s", { fontStyle: "italic underline strikethrough" }), |
| 38 | + new TextMateRule("renpy.meta.b renpy.meta.u renpy.meta.s", { fontStyle: "bold underline strikethrough" }), |
24 | 39 |
|
25 |
| - { scope: "renpy.meta.i renpy.meta.b renpy.meta.u renpy.meta.s", settings: { fontStyle: "italic bold underline strikethrough" } }, |
| 40 | + new TextMateRule("renpy.meta.i renpy.meta.b renpy.meta.u renpy.meta.s", { fontStyle: "italic bold underline strikethrough" }), |
26 | 41 |
|
27 |
| - { scope: "renpy.meta.color.text", settings: { foreground: "#ffffff" } }, |
28 |
| -]; |
| 42 | + new TextMateRule("renpy.meta.color.text", { foreground: "#ffffff" }), |
| 43 | +]); |
29 | 44 |
|
30 |
| -export function injectCustomTextmateTokens(rules: TextMateRule[]) { |
| 45 | +export function injectCustomTextmateTokens(rules: ValueEqualsSet<TextMateRule>) { |
31 | 46 | const tokensConfig = workspace.getConfiguration("editor");
|
32 | 47 |
|
33 | 48 | // If the config didn't exist yet, push the default tokens
|
34 | 49 | let tokenColorCustomizations = tokensConfig.get<TextMateRules>("tokenColorCustomizations");
|
35 |
| - if (tokenColorCustomizations === undefined || tokenColorCustomizations.textMateRules === undefined) tokenColorCustomizations = { textMateRules: customFontStyleRules }; |
| 50 | + if (tokenColorCustomizations === undefined || tokenColorCustomizations.textMateRules === undefined) { |
| 51 | + tokenColorCustomizations = { textMateRules: customFontStyleRules.toArray() }; |
| 52 | + } |
36 | 53 |
|
37 | 54 | const currentRules = tokenColorCustomizations.textMateRules;
|
38 | 55 |
|
39 | 56 | // Build the new rules for this file
|
40 |
| - const newRules = customFontStyleRules.concat(rules); // Always add the default rules |
41 |
| - const filteredRules = newRules.filter((y) => { |
42 |
| - return !currentRules.some((x) => { |
43 |
| - if (x.scope instanceof Array && y.scope instanceof Array) { |
44 |
| - return x.scope.length === y.scope.length && x.scope.every((value, index) => value === y.scope[index]); |
45 |
| - } |
46 |
| - |
47 |
| - return x.scope === y.scope || (x.scope === y.scope && (x.settings.foreground !== y.settings.foreground || x.settings.fontStyle !== y.settings.fontStyle)); |
48 |
| - }); |
49 |
| - }); |
| 57 | + const newRules = customFontStyleRules.addRange(rules); // Always add the default rules |
| 58 | + for (const rule of currentRules) { |
| 59 | + newRules.add(new TextMateRule(rule.scope, rule.settings)); |
| 60 | + } |
50 | 61 |
|
51 |
| - if (filteredRules.length !== 0) { |
52 |
| - tokenColorCustomizations.textMateRules = currentRules.concat(filteredRules); |
| 62 | + if (newRules.size !== 0) { |
| 63 | + tokenColorCustomizations.textMateRules = newRules.toArray(); |
53 | 64 | tokensConfig.update("tokenColorCustomizations", tokenColorCustomizations, ConfigurationTarget.Workspace).then(
|
54 | 65 | () => {
|
55 | 66 | console.log("Successfully updated the tokenColorCustomizations config");
|
|
0 commit comments