diff options
author | Aleksey Kladov <[email protected]> | 2019-12-31 02:33:00 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-12-31 02:33:00 +0000 |
commit | f984ef26528eca686abbb946b3b363dfe6d74822 (patch) | |
tree | 75d70fd728114cf3bee0bea997c9fa6c518ba3df /editors/code | |
parent | cfb086592995a54828f23734a260d387db9ea926 (diff) |
Switch impure functional style to pure imperative
Diffstat (limited to 'editors/code')
-rw-r--r-- | editors/code/src/config.ts | 2 | ||||
-rw-r--r-- | editors/code/src/highlighting.ts | 8 | ||||
-rw-r--r-- | editors/code/src/scopes.ts | 150 | ||||
-rw-r--r-- | editors/code/tsconfig.json | 2 |
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 @@ | |||
1 | import * as vscode from 'vscode'; | 1 | import * as vscode from 'vscode'; |
2 | import * as scopes from './scopes'; | ||
3 | import * as scopesMapper from './scopes_mapper'; | 2 | import * as scopesMapper from './scopes_mapper'; |
4 | 3 | ||
5 | const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG; | 4 | const 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'; | |||
3 | import * as seedrandom_ from 'seedrandom'; | 3 | import * as seedrandom_ from 'seedrandom'; |
4 | const seedrandom = seedrandom_; // https://github.com/jvandemo/generator-angular2-library/issues/221#issuecomment-355945207 | 4 | const seedrandom = seedrandom_; // https://github.com/jvandemo/generator-angular2-library/issues/221#issuecomment-355945207 |
5 | 5 | ||
6 | import * as scopes from './scopes'; | 6 | import { loadThemeColors, TextMateRuleSettings } from './scopes'; |
7 | import * as scopesMapper from './scopes_mapper'; | 7 | import * as scopesMapper from './scopes_mapper'; |
8 | 8 | ||
9 | import { Ctx } from './ctx'; | 9 | import { 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 | ||
234 | function createDecorationFromTextmate( | 236 | function 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'; | |||
3 | import * as path from 'path'; | 3 | import * as path from 'path'; |
4 | import * as vscode from 'vscode'; | 4 | import * as vscode from 'vscode'; |
5 | 5 | ||
6 | export interface TextMateRule { | ||
7 | scope: string | string[]; | ||
8 | settings: TextMateRuleSettings; | ||
9 | } | ||
10 | |||
11 | export interface TextMateRuleSettings { | 6 | export 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 | ||
18 | const rules = new Map<string, TextMateRuleSettings>(); | ||
19 | |||
20 | export 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 |
25 | export function load() { | 13 | export 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 | 26 | function loadThemeNamed(themeName: string): Map<string, TextMateRuleSettings> { | |
46 | |||
47 | // Find current theme on disk | ||
48 | function 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 | ||
85 | function loadThemeFile(themePath: string) { | 54 | function 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 | 74 | interface 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 | 79 | function 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 | ||
103 | function mergeRuleSettings( | 92 | function 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 | ||
119 | function updateRules( | 103 | function 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 | |||
128 | function 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", |