mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
Switch impure functional style to pure imperative
This commit is contained in:
parent
cfb0865929
commit
f984ef2652
4 changed files with 66 additions and 94 deletions
|
@ -1,5 +1,4 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as scopes from './scopes';
|
||||
import * as scopesMapper from './scopes_mapper';
|
||||
|
||||
const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG;
|
||||
|
@ -60,7 +59,6 @@ export class Config {
|
|||
if (config.has('highlightingOn')) {
|
||||
this.highlightingOn = config.get('highlightingOn') as boolean;
|
||||
if (this.highlightingOn) {
|
||||
scopes.load();
|
||||
scopesMapper.load();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import * as lc from 'vscode-languageclient';
|
|||
import * as seedrandom_ from 'seedrandom';
|
||||
const seedrandom = seedrandom_; // https://github.com/jvandemo/generator-angular2-library/issues/221#issuecomment-355945207
|
||||
|
||||
import * as scopes from './scopes';
|
||||
import { loadThemeColors, TextMateRuleSettings } from './scopes';
|
||||
import * as scopesMapper from './scopes_mapper';
|
||||
|
||||
import { Ctx } from './ctx';
|
||||
|
@ -172,11 +172,13 @@ function initDecorations(): Map<
|
|||
string,
|
||||
vscode.TextEditorDecorationType
|
||||
> {
|
||||
const themeColors = loadThemeColors();
|
||||
|
||||
const decoration = (
|
||||
tag: string,
|
||||
textDecoration?: string,
|
||||
): [string, vscode.TextEditorDecorationType] => {
|
||||
const rule = scopesMapper.toRule(tag, scopes.find);
|
||||
const rule = scopesMapper.toRule(tag, it => themeColors.get(it));
|
||||
|
||||
if (rule) {
|
||||
const decor = createDecorationFromTextmate(rule);
|
||||
|
@ -232,7 +234,7 @@ function initDecorations(): Map<
|
|||
}
|
||||
|
||||
function createDecorationFromTextmate(
|
||||
themeStyle: scopes.TextMateRuleSettings,
|
||||
themeStyle: TextMateRuleSettings,
|
||||
): vscode.TextEditorDecorationType {
|
||||
const decorationOptions: vscode.DecorationRenderOptions = {};
|
||||
decorationOptions.rangeBehavior = vscode.DecorationRangeBehavior.OpenOpen;
|
||||
|
|
|
@ -3,28 +3,14 @@ import * as jsonc from 'jsonc-parser';
|
|||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export interface TextMateRule {
|
||||
scope: string | string[];
|
||||
settings: TextMateRuleSettings;
|
||||
}
|
||||
|
||||
export interface TextMateRuleSettings {
|
||||
foreground?: string;
|
||||
background?: string;
|
||||
fontStyle?: string;
|
||||
}
|
||||
|
||||
// Current theme colors
|
||||
const rules = new Map<string, TextMateRuleSettings>();
|
||||
|
||||
export function find(scope: string): TextMateRuleSettings | undefined {
|
||||
return rules.get(scope);
|
||||
}
|
||||
|
||||
// Load all textmate scopes in the currently active theme
|
||||
export function load() {
|
||||
// Remove any previous theme
|
||||
rules.clear();
|
||||
export function loadThemeColors(): Map<string, TextMateRuleSettings> {
|
||||
// Find out current color theme
|
||||
const themeName = vscode.workspace
|
||||
.getConfiguration('workbench')
|
||||
|
@ -32,20 +18,12 @@ export function load() {
|
|||
|
||||
if (typeof themeName !== 'string') {
|
||||
// console.warn('workbench.colorTheme is', themeName)
|
||||
return;
|
||||
}
|
||||
// Try to load colors from that theme
|
||||
try {
|
||||
loadThemeNamed(themeName);
|
||||
} catch (e) {
|
||||
// console.warn('failed to load theme', themeName, e)
|
||||
return new Map();
|
||||
}
|
||||
return loadThemeNamed(themeName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Find current theme on disk
|
||||
function loadThemeNamed(themeName: string) {
|
||||
function loadThemeNamed(themeName: string): Map<string, TextMateRuleSettings> {
|
||||
function isTheme(extension: vscode.Extension<any>): boolean {
|
||||
return (
|
||||
extension.extensionKind === vscode.ExtensionKind.UI &&
|
||||
|
@ -54,83 +32,77 @@ function loadThemeNamed(themeName: string) {
|
|||
);
|
||||
}
|
||||
|
||||
const themePaths = vscode.extensions.all
|
||||
let themePaths = vscode.extensions.all
|
||||
.filter(isTheme)
|
||||
.reduce((list, extension) => {
|
||||
return extension.packageJSON.contributes.themes
|
||||
.filter(
|
||||
(element: any) =>
|
||||
(element.id || element.label) === themeName,
|
||||
)
|
||||
.map((element: any) =>
|
||||
path.join(extension.extensionPath, element.path),
|
||||
)
|
||||
.concat(list);
|
||||
}, Array<string>());
|
||||
.flatMap(ext => {
|
||||
return ext.packageJSON.contributes.themes
|
||||
.filter((it: any) => (it.id || it.label) === themeName)
|
||||
.map((it: any) => path.join(ext.extensionPath, it.path));
|
||||
})
|
||||
|
||||
themePaths.forEach(loadThemeFile);
|
||||
const res = new Map();
|
||||
for (const themePath of themePaths) {
|
||||
mergeInto(res, loadThemeFile(themePath))
|
||||
}
|
||||
|
||||
const tokenColorCustomizations: [any] = [
|
||||
vscode.workspace
|
||||
.getConfiguration('editor')
|
||||
.get('tokenColorCustomizations'),
|
||||
];
|
||||
const customizations: any = vscode.workspace.getConfiguration('editor').get('tokenColorCustomizations');
|
||||
mergeInto(res, loadColors(customizations?.textMateRules ?? []))
|
||||
|
||||
tokenColorCustomizations
|
||||
.filter(custom => custom && custom.textMateRules)
|
||||
.map(custom => custom.textMateRules)
|
||||
.forEach(loadColors);
|
||||
return res;
|
||||
}
|
||||
|
||||
function loadThemeFile(themePath: string) {
|
||||
const themeContent = [themePath]
|
||||
.filter(it => fs.statSync(it).isFile())
|
||||
.map(it => fs.readFileSync(it, 'utf8'))
|
||||
.map(it => jsonc.parse(it))
|
||||
.filter(theme => theme);
|
||||
function loadThemeFile(themePath: string): Map<string, TextMateRuleSettings> {
|
||||
let text;
|
||||
try {
|
||||
text = fs.readFileSync(themePath, 'utf8')
|
||||
} catch {
|
||||
return new Map();
|
||||
}
|
||||
const obj = jsonc.parse(text);
|
||||
const tokenColors = obj?.tokenColors ?? [];
|
||||
const res = loadColors(tokenColors);
|
||||
|
||||
themeContent
|
||||
.filter(theme => theme.tokenColors)
|
||||
.map(theme => theme.tokenColors)
|
||||
.forEach(loadColors);
|
||||
for (const include in obj?.include ?? []) {
|
||||
const includePath = path.join(path.dirname(themePath), include);
|
||||
const tmp = loadThemeFile(includePath);
|
||||
mergeInto(res, tmp);
|
||||
}
|
||||
|
||||
themeContent
|
||||
.filter(theme => theme.include)
|
||||
.map(theme => path.join(path.dirname(themePath), theme.include))
|
||||
.forEach(loadThemeFile);
|
||||
return res;
|
||||
}
|
||||
|
||||
interface TextMateRule {
|
||||
scope: string | string[];
|
||||
settings: TextMateRuleSettings;
|
||||
}
|
||||
|
||||
function loadColors(textMateRules: TextMateRule[]): Map<string, TextMateRuleSettings> {
|
||||
const res = new Map();
|
||||
for (const rule of textMateRules) {
|
||||
const scopes = typeof rule.scope === 'string'
|
||||
? [rule.scope]
|
||||
: rule.scope;
|
||||
for (const scope of scopes) {
|
||||
res.set(scope, rule.settings)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
function mergeRuleSettings(
|
||||
defaultSetting: TextMateRuleSettings | undefined,
|
||||
override: TextMateRuleSettings,
|
||||
): TextMateRuleSettings {
|
||||
if (defaultSetting === undefined) {
|
||||
return override;
|
||||
return {
|
||||
foreground: defaultSetting?.foreground ?? override.foreground,
|
||||
background: defaultSetting?.background ?? override.background,
|
||||
fontStyle: defaultSetting?.fontStyle ?? override.fontStyle,
|
||||
}
|
||||
const mergedRule = defaultSetting;
|
||||
|
||||
mergedRule.background = override.background || defaultSetting.background;
|
||||
mergedRule.foreground = override.foreground || defaultSetting.foreground;
|
||||
mergedRule.fontStyle = override.fontStyle || defaultSetting.foreground;
|
||||
|
||||
return mergedRule;
|
||||
}
|
||||
|
||||
function updateRules(
|
||||
scope: string,
|
||||
updatedSettings: TextMateRuleSettings,
|
||||
): void {
|
||||
[rules.get(scope)]
|
||||
.map(settings => mergeRuleSettings(settings, updatedSettings))
|
||||
.forEach(settings => rules.set(scope, settings));
|
||||
}
|
||||
|
||||
function loadColors(textMateRules: TextMateRule[]): void {
|
||||
textMateRules.forEach(rule => {
|
||||
if (typeof rule.scope === 'string') {
|
||||
updateRules(rule.scope, rule.settings);
|
||||
} else if (rule.scope instanceof Array) {
|
||||
rule.scope.forEach(scope => updateRules(scope, rule.settings));
|
||||
}
|
||||
});
|
||||
function mergeInto(dst: Map<string, TextMateRuleSettings>, addition: Map<string, TextMateRuleSettings>) {
|
||||
addition.forEach((value, key) => {
|
||||
const merged = mergeRuleSettings(dst.get(key), value)
|
||||
dst.set(key, merged)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"target": "es2018",
|
||||
"outDir": "out",
|
||||
"lib": [
|
||||
"es2018"
|
||||
"es2019"
|
||||
],
|
||||
"sourceMap": true,
|
||||
"rootDir": "src",
|
||||
|
|
Loading…
Reference in a new issue