aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-12-31 02:33:00 +0000
committerAleksey Kladov <[email protected]>2019-12-31 02:33:00 +0000
commitf984ef26528eca686abbb946b3b363dfe6d74822 (patch)
tree75d70fd728114cf3bee0bea997c9fa6c518ba3df
parentcfb086592995a54828f23734a260d387db9ea926 (diff)
Switch impure functional style to pure imperative
-rw-r--r--editors/code/src/config.ts2
-rw-r--r--editors/code/src/highlighting.ts8
-rw-r--r--editors/code/src/scopes.ts150
-rw-r--r--editors/code/tsconfig.json2
4 files changed, 67 insertions, 95 deletions
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index e323110a4..f63d1ddce 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -1,5 +1,4 @@
1import * as vscode from 'vscode'; 1import * as vscode from 'vscode';
2import * as scopes from './scopes';
3import * as scopesMapper from './scopes_mapper'; 2import * as scopesMapper from './scopes_mapper';
4 3
5const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG; 4const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG;
@@ -60,7 +59,6 @@ export class Config {
60 if (config.has('highlightingOn')) { 59 if (config.has('highlightingOn')) {
61 this.highlightingOn = config.get('highlightingOn') as boolean; 60 this.highlightingOn = config.get('highlightingOn') as boolean;
62 if (this.highlightingOn) { 61 if (this.highlightingOn) {
63 scopes.load();
64 scopesMapper.load(); 62 scopesMapper.load();
65 } 63 }
66 } 64 }
diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts
index 4c2e7f67b..5e9cbe0de 100644
--- a/editors/code/src/highlighting.ts
+++ b/editors/code/src/highlighting.ts
@@ -3,7 +3,7 @@ import * as lc from 'vscode-languageclient';
3import * as seedrandom_ from 'seedrandom'; 3import * as seedrandom_ from 'seedrandom';
4const seedrandom = seedrandom_; // https://github.com/jvandemo/generator-angular2-library/issues/221#issuecomment-355945207 4const seedrandom = seedrandom_; // https://github.com/jvandemo/generator-angular2-library/issues/221#issuecomment-355945207
5 5
6import * as scopes from './scopes'; 6import { loadThemeColors, TextMateRuleSettings } from './scopes';
7import * as scopesMapper from './scopes_mapper'; 7import * as scopesMapper from './scopes_mapper';
8 8
9import { Ctx } from './ctx'; 9import { Ctx } from './ctx';
@@ -172,11 +172,13 @@ function initDecorations(): Map<
172 string, 172 string,
173 vscode.TextEditorDecorationType 173 vscode.TextEditorDecorationType
174> { 174> {
175 const themeColors = loadThemeColors();
176
175 const decoration = ( 177 const decoration = (
176 tag: string, 178 tag: string,
177 textDecoration?: string, 179 textDecoration?: string,
178 ): [string, vscode.TextEditorDecorationType] => { 180 ): [string, vscode.TextEditorDecorationType] => {
179 const rule = scopesMapper.toRule(tag, scopes.find); 181 const rule = scopesMapper.toRule(tag, it => themeColors.get(it));
180 182
181 if (rule) { 183 if (rule) {
182 const decor = createDecorationFromTextmate(rule); 184 const decor = createDecorationFromTextmate(rule);
@@ -232,7 +234,7 @@ function initDecorations(): Map<
232} 234}
233 235
234function createDecorationFromTextmate( 236function createDecorationFromTextmate(
235 themeStyle: scopes.TextMateRuleSettings, 237 themeStyle: TextMateRuleSettings,
236): vscode.TextEditorDecorationType { 238): vscode.TextEditorDecorationType {
237 const decorationOptions: vscode.DecorationRenderOptions = {}; 239 const decorationOptions: vscode.DecorationRenderOptions = {};
238 decorationOptions.rangeBehavior = vscode.DecorationRangeBehavior.OpenOpen; 240 decorationOptions.rangeBehavior = vscode.DecorationRangeBehavior.OpenOpen;
diff --git a/editors/code/src/scopes.ts b/editors/code/src/scopes.ts
index 1229f0fb9..73fabbf54 100644
--- a/editors/code/src/scopes.ts
+++ b/editors/code/src/scopes.ts
@@ -3,28 +3,14 @@ import * as jsonc from 'jsonc-parser';
3import * as path from 'path'; 3import * as path from 'path';
4import * as vscode from 'vscode'; 4import * as vscode from 'vscode';
5 5
6export interface TextMateRule {
7 scope: string | string[];
8 settings: TextMateRuleSettings;
9}
10
11export interface TextMateRuleSettings { 6export interface TextMateRuleSettings {
12 foreground?: string; 7 foreground?: string;
13 background?: string; 8 background?: string;
14 fontStyle?: string; 9 fontStyle?: string;
15} 10}
16 11
17// Current theme colors
18const rules = new Map<string, TextMateRuleSettings>();
19
20export function find(scope: string): TextMateRuleSettings | undefined {
21 return rules.get(scope);
22}
23
24// Load all textmate scopes in the currently active theme 12// Load all textmate scopes in the currently active theme
25export function load() { 13export function loadThemeColors(): Map<string, TextMateRuleSettings> {
26 // Remove any previous theme
27 rules.clear();
28 // Find out current color theme 14 // Find out current color theme
29 const themeName = vscode.workspace 15 const themeName = vscode.workspace
30 .getConfiguration('workbench') 16 .getConfiguration('workbench')
@@ -32,20 +18,12 @@ export function load() {
32 18
33 if (typeof themeName !== 'string') { 19 if (typeof themeName !== 'string') {
34 // console.warn('workbench.colorTheme is', themeName) 20 // console.warn('workbench.colorTheme is', themeName)
35 return; 21 return new Map();
36 }
37 // Try to load colors from that theme
38 try {
39 loadThemeNamed(themeName);
40 } catch (e) {
41 // console.warn('failed to load theme', themeName, e)
42 } 22 }
23 return loadThemeNamed(themeName);
43} 24}
44 25
45 26function loadThemeNamed(themeName: string): Map<string, TextMateRuleSettings> {
46
47// Find current theme on disk
48function loadThemeNamed(themeName: string) {
49 function isTheme(extension: vscode.Extension<any>): boolean { 27 function isTheme(extension: vscode.Extension<any>): boolean {
50 return ( 28 return (
51 extension.extensionKind === vscode.ExtensionKind.UI && 29 extension.extensionKind === vscode.ExtensionKind.UI &&
@@ -54,83 +32,77 @@ function loadThemeNamed(themeName: string) {
54 ); 32 );
55 } 33 }
56 34
57 const themePaths = vscode.extensions.all 35 let themePaths = vscode.extensions.all
58 .filter(isTheme) 36 .filter(isTheme)
59 .reduce((list, extension) => { 37 .flatMap(ext => {
60 return extension.packageJSON.contributes.themes 38 return ext.packageJSON.contributes.themes
61 .filter( 39 .filter((it: any) => (it.id || it.label) === themeName)
62 (element: any) => 40 .map((it: any) => path.join(ext.extensionPath, it.path));
63 (element.id || element.label) === themeName, 41 })
64 ) 42
65 .map((element: any) => 43 const res = new Map();
66 path.join(extension.extensionPath, element.path), 44 for (const themePath of themePaths) {
67 ) 45 mergeInto(res, loadThemeFile(themePath))
68 .concat(list); 46 }
69 }, Array<string>());
70
71 themePaths.forEach(loadThemeFile);
72 47
73 const tokenColorCustomizations: [any] = [ 48 const customizations: any = vscode.workspace.getConfiguration('editor').get('tokenColorCustomizations');
74 vscode.workspace 49 mergeInto(res, loadColors(customizations?.textMateRules ?? []))
75 .getConfiguration('editor')
76 .get('tokenColorCustomizations'),
77 ];
78 50
79 tokenColorCustomizations 51 return res;
80 .filter(custom => custom && custom.textMateRules)
81 .map(custom => custom.textMateRules)
82 .forEach(loadColors);
83} 52}
84 53
85function loadThemeFile(themePath: string) { 54function loadThemeFile(themePath: string): Map<string, TextMateRuleSettings> {
86 const themeContent = [themePath] 55 let text;
87 .filter(it => fs.statSync(it).isFile()) 56 try {
88 .map(it => fs.readFileSync(it, 'utf8')) 57 text = fs.readFileSync(themePath, 'utf8')
89 .map(it => jsonc.parse(it)) 58 } catch {
90 .filter(theme => theme); 59 return new Map();
60 }
61 const obj = jsonc.parse(text);
62 const tokenColors = obj?.tokenColors ?? [];
63 const res = loadColors(tokenColors);
64
65 for (const include in obj?.include ?? []) {
66 const includePath = path.join(path.dirname(themePath), include);
67 const tmp = loadThemeFile(includePath);
68 mergeInto(res, tmp);
69 }
70
71 return res;
72}
91 73
92 themeContent 74interface TextMateRule {
93 .filter(theme => theme.tokenColors) 75 scope: string | string[];
94 .map(theme => theme.tokenColors) 76 settings: TextMateRuleSettings;
95 .forEach(loadColors); 77}
96 78
97 themeContent 79function loadColors(textMateRules: TextMateRule[]): Map<string, TextMateRuleSettings> {
98 .filter(theme => theme.include) 80 const res = new Map();
99 .map(theme => path.join(path.dirname(themePath), theme.include)) 81 for (const rule of textMateRules) {
100 .forEach(loadThemeFile); 82 const scopes = typeof rule.scope === 'string'
83 ? [rule.scope]
84 : rule.scope;
85 for (const scope of scopes) {
86 res.set(scope, rule.settings)
87 }
88 }
89 return res
101} 90}
102 91
103function mergeRuleSettings( 92function mergeRuleSettings(
104 defaultSetting: TextMateRuleSettings | undefined, 93 defaultSetting: TextMateRuleSettings | undefined,
105 override: TextMateRuleSettings, 94 override: TextMateRuleSettings,
106): TextMateRuleSettings { 95): TextMateRuleSettings {
107 if (defaultSetting === undefined) { 96 return {
108 return override; 97 foreground: defaultSetting?.foreground ?? override.foreground,
98 background: defaultSetting?.background ?? override.background,
99 fontStyle: defaultSetting?.fontStyle ?? override.fontStyle,
109 } 100 }
110 const mergedRule = defaultSetting;
111
112 mergedRule.background = override.background || defaultSetting.background;
113 mergedRule.foreground = override.foreground || defaultSetting.foreground;
114 mergedRule.fontStyle = override.fontStyle || defaultSetting.foreground;
115
116 return mergedRule;
117} 101}
118 102
119function updateRules( 103function mergeInto(dst: Map<string, TextMateRuleSettings>, addition: Map<string, TextMateRuleSettings>) {
120 scope: string, 104 addition.forEach((value, key) => {
121 updatedSettings: TextMateRuleSettings, 105 const merged = mergeRuleSettings(dst.get(key), value)
122): void { 106 dst.set(key, merged)
123 [rules.get(scope)] 107 })
124 .map(settings => mergeRuleSettings(settings, updatedSettings))
125 .forEach(settings => rules.set(scope, settings));
126}
127
128function loadColors(textMateRules: TextMateRule[]): void {
129 textMateRules.forEach(rule => {
130 if (typeof rule.scope === 'string') {
131 updateRules(rule.scope, rule.settings);
132 } else if (rule.scope instanceof Array) {
133 rule.scope.forEach(scope => updateRules(scope, rule.settings));
134 }
135 });
136} 108}
diff --git a/editors/code/tsconfig.json b/editors/code/tsconfig.json
index fe3b40f34..e60eb8e5e 100644
--- a/editors/code/tsconfig.json
+++ b/editors/code/tsconfig.json
@@ -4,7 +4,7 @@
4 "target": "es2018", 4 "target": "es2018",
5 "outDir": "out", 5 "outDir": "out",
6 "lib": [ 6 "lib": [
7 "es2018" 7 "es2019"
8 ], 8 ],
9 "sourceMap": true, 9 "sourceMap": true,
10 "rootDir": "src", 10 "rootDir": "src",