Skip to content

Commit f984ef2

Browse files
committed
Switch impure functional style to pure imperative
1 parent cfb0865 commit f984ef2

File tree

4 files changed

+67
-95
lines changed

4 files changed

+67
-95
lines changed

editors/code/src/config.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import * as vscode from 'vscode';
2-
import * as scopes from './scopes';
32
import * as scopesMapper from './scopes_mapper';
43

54
const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG;
@@ -60,7 +59,6 @@ export class Config {
6059
if (config.has('highlightingOn')) {
6160
this.highlightingOn = config.get('highlightingOn') as boolean;
6261
if (this.highlightingOn) {
63-
scopes.load();
6462
scopesMapper.load();
6563
}
6664
}

editors/code/src/highlighting.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as lc from 'vscode-languageclient';
33
import * as seedrandom_ from 'seedrandom';
44
const seedrandom = seedrandom_; // https://github.com/jvandemo/generator-angular2-library/issues/221#issuecomment-355945207
55

6-
import * as scopes from './scopes';
6+
import { loadThemeColors, TextMateRuleSettings } from './scopes';
77
import * as scopesMapper from './scopes_mapper';
88

99
import { Ctx } from './ctx';
@@ -172,11 +172,13 @@ function initDecorations(): Map<
172172
string,
173173
vscode.TextEditorDecorationType
174174
> {
175+
const themeColors = loadThemeColors();
176+
175177
const decoration = (
176178
tag: string,
177179
textDecoration?: string,
178180
): [string, vscode.TextEditorDecorationType] => {
179-
const rule = scopesMapper.toRule(tag, scopes.find);
181+
const rule = scopesMapper.toRule(tag, it => themeColors.get(it));
180182

181183
if (rule) {
182184
const decor = createDecorationFromTextmate(rule);
@@ -232,7 +234,7 @@ function initDecorations(): Map<
232234
}
233235

234236
function createDecorationFromTextmate(
235-
themeStyle: scopes.TextMateRuleSettings,
237+
themeStyle: TextMateRuleSettings,
236238
): vscode.TextEditorDecorationType {
237239
const decorationOptions: vscode.DecorationRenderOptions = {};
238240
decorationOptions.rangeBehavior = vscode.DecorationRangeBehavior.OpenOpen;

editors/code/src/scopes.ts

Lines changed: 61 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,27 @@ import * as jsonc from 'jsonc-parser';
33
import * as path from 'path';
44
import * as vscode from 'vscode';
55

6-
export interface TextMateRule {
7-
scope: string | string[];
8-
settings: TextMateRuleSettings;
9-
}
10-
116
export interface TextMateRuleSettings {
127
foreground?: string;
138
background?: string;
149
fontStyle?: string;
1510
}
1611

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-
2412
// Load all textmate scopes in the currently active theme
25-
export function load() {
26-
// Remove any previous theme
27-
rules.clear();
13+
export function loadThemeColors(): Map<string, TextMateRuleSettings> {
2814
// Find out current color theme
2915
const themeName = vscode.workspace
3016
.getConfiguration('workbench')
3117
.get('colorTheme');
3218

3319
if (typeof themeName !== 'string') {
3420
// console.warn('workbench.colorTheme is', themeName)
35-
return;
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)
21+
return new Map();
4222
}
23+
return loadThemeNamed(themeName);
4324
}
4425

45-
46-
47-
// Find current theme on disk
48-
function loadThemeNamed(themeName: string) {
26+
function loadThemeNamed(themeName: string): Map<string, TextMateRuleSettings> {
4927
function isTheme(extension: vscode.Extension<any>): boolean {
5028
return (
5129
extension.extensionKind === vscode.ExtensionKind.UI &&
@@ -54,83 +32,77 @@ function loadThemeNamed(themeName: string) {
5432
);
5533
}
5634

57-
const themePaths = vscode.extensions.all
35+
let themePaths = vscode.extensions.all
5836
.filter(isTheme)
59-
.reduce((list, extension) => {
60-
return extension.packageJSON.contributes.themes
61-
.filter(
62-
(element: any) =>
63-
(element.id || element.label) === themeName,
64-
)
65-
.map((element: any) =>
66-
path.join(extension.extensionPath, element.path),
67-
)
68-
.concat(list);
69-
}, Array<string>());
70-
71-
themePaths.forEach(loadThemeFile);
37+
.flatMap(ext => {
38+
return ext.packageJSON.contributes.themes
39+
.filter((it: any) => (it.id || it.label) === themeName)
40+
.map((it: any) => path.join(ext.extensionPath, it.path));
41+
})
42+
43+
const res = new Map();
44+
for (const themePath of themePaths) {
45+
mergeInto(res, loadThemeFile(themePath))
46+
}
7247

73-
const tokenColorCustomizations: [any] = [
74-
vscode.workspace
75-
.getConfiguration('editor')
76-
.get('tokenColorCustomizations'),
77-
];
48+
const customizations: any = vscode.workspace.getConfiguration('editor').get('tokenColorCustomizations');
49+
mergeInto(res, loadColors(customizations?.textMateRules ?? []))
7850

79-
tokenColorCustomizations
80-
.filter(custom => custom && custom.textMateRules)
81-
.map(custom => custom.textMateRules)
82-
.forEach(loadColors);
51+
return res;
8352
}
8453

85-
function loadThemeFile(themePath: string) {
86-
const themeContent = [themePath]
87-
.filter(it => fs.statSync(it).isFile())
88-
.map(it => fs.readFileSync(it, 'utf8'))
89-
.map(it => jsonc.parse(it))
90-
.filter(theme => theme);
54+
function loadThemeFile(themePath: string): Map<string, TextMateRuleSettings> {
55+
let text;
56+
try {
57+
text = fs.readFileSync(themePath, 'utf8')
58+
} catch {
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+
}
9173

92-
themeContent
93-
.filter(theme => theme.tokenColors)
94-
.map(theme => theme.tokenColors)
95-
.forEach(loadColors);
74+
interface TextMateRule {
75+
scope: string | string[];
76+
settings: TextMateRuleSettings;
77+
}
9678

97-
themeContent
98-
.filter(theme => theme.include)
99-
.map(theme => path.join(path.dirname(themePath), theme.include))
100-
.forEach(loadThemeFile);
79+
function loadColors(textMateRules: TextMateRule[]): Map<string, TextMateRuleSettings> {
80+
const res = new Map();
81+
for (const rule of textMateRules) {
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
10190
}
10291

10392
function mergeRuleSettings(
10493
defaultSetting: TextMateRuleSettings | undefined,
10594
override: TextMateRuleSettings,
10695
): TextMateRuleSettings {
107-
if (defaultSetting === undefined) {
108-
return override;
96+
return {
97+
foreground: defaultSetting?.foreground ?? override.foreground,
98+
background: defaultSetting?.background ?? override.background,
99+
fontStyle: defaultSetting?.fontStyle ?? override.fontStyle,
109100
}
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;
117101
}
118102

119-
function updateRules(
120-
scope: string,
121-
updatedSettings: TextMateRuleSettings,
122-
): void {
123-
[rules.get(scope)]
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-
});
103+
function mergeInto(dst: Map<string, TextMateRuleSettings>, addition: Map<string, TextMateRuleSettings>) {
104+
addition.forEach((value, key) => {
105+
const merged = mergeRuleSettings(dst.get(key), value)
106+
dst.set(key, merged)
107+
})
136108
}

editors/code/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"target": "es2018",
55
"outDir": "out",
66
"lib": [
7-
"es2018"
7+
"es2019"
88
],
99
"sourceMap": true,
1010
"rootDir": "src",

0 commit comments

Comments
 (0)