mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-17 02:08:30 +00:00
Merge #2702
2702: Drop support for legacy colorization r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
46952985a0
8 changed files with 187 additions and 271 deletions
|
@ -38,12 +38,12 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
<span class="keyword">fn</span> <span class="function">main</span>() {
|
||||
<span class="macro">println</span><span class="macro">!</span>(<span class="string">"Hello, {}!"</span>, <span class="literal.numeric">92</span>);
|
||||
|
||||
<span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">vec</span> = <span class="text">Vec</span>::<span class="text">new</span>();
|
||||
<span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">vec</span> = Vec::new();
|
||||
<span class="keyword.control">if</span> <span class="keyword">true</span> {
|
||||
<span class="keyword">let</span> <span class="variable">x</span> = <span class="literal.numeric">92</span>;
|
||||
<span class="variable.mut">vec</span>.<span class="text">push</span>(<span class="type">Foo</span> { <span class="field">x</span>, <span class="field">y</span>: <span class="literal.numeric">1</span> });
|
||||
<span class="variable.mut">vec</span>.push(<span class="type">Foo</span> { <span class="field">x</span>, <span class="field">y</span>: <span class="literal.numeric">1</span> });
|
||||
}
|
||||
<span class="keyword.unsafe">unsafe</span> { <span class="variable.mut">vec</span>.<span class="text">set_len</span>(<span class="literal.numeric">0</span>); }
|
||||
<span class="keyword.unsafe">unsafe</span> { <span class="variable.mut">vec</span>.set_len(<span class="literal.numeric">0</span>); }
|
||||
|
||||
<span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">x</span> = <span class="literal.numeric">42</span>;
|
||||
<span class="keyword">let</span> <span class="variable.mut">y</span> = &<span class="keyword">mut</span> <span class="variable.mut">x</span>;
|
||||
|
|
|
@ -25,11 +25,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
</style>
|
||||
<pre><code><span class="keyword">fn</span> <span class="function">main</span>() {
|
||||
<span class="keyword">let</span> <span class="variable" data-binding-hash="8723171760279909834" style="color: hsl(307,91%,75%);">hello</span> = <span class="string">"hello"</span>;
|
||||
<span class="keyword">let</span> <span class="variable" data-binding-hash="14702933417323009544" style="color: hsl(108,90%,49%);">x</span> = <span class="variable" data-binding-hash="8723171760279909834" style="color: hsl(307,91%,75%);">hello</span>.<span class="text">to_string</span>();
|
||||
<span class="keyword">let</span> <span class="variable" data-binding-hash="5443150872754369068" style="color: hsl(215,43%,43%);">y</span> = <span class="variable" data-binding-hash="8723171760279909834" style="color: hsl(307,91%,75%);">hello</span>.<span class="text">to_string</span>();
|
||||
<span class="keyword">let</span> <span class="variable" data-binding-hash="14702933417323009544" style="color: hsl(108,90%,49%);">x</span> = <span class="variable" data-binding-hash="8723171760279909834" style="color: hsl(307,91%,75%);">hello</span>.to_string();
|
||||
<span class="keyword">let</span> <span class="variable" data-binding-hash="5443150872754369068" style="color: hsl(215,43%,43%);">y</span> = <span class="variable" data-binding-hash="8723171760279909834" style="color: hsl(307,91%,75%);">hello</span>.to_string();
|
||||
|
||||
<span class="keyword">let</span> <span class="variable" data-binding-hash="17358108296605513516" style="color: hsl(331,46%,60%);">x</span> = <span class="string">"other color please!"</span>;
|
||||
<span class="keyword">let</span> <span class="variable" data-binding-hash="2073121142529774969" style="color: hsl(320,43%,74%);">y</span> = <span class="variable" data-binding-hash="17358108296605513516" style="color: hsl(331,46%,60%);">x</span>.<span class="text">to_string</span>();
|
||||
<span class="keyword">let</span> <span class="variable" data-binding-hash="2073121142529774969" style="color: hsl(320,43%,74%);">y</span> = <span class="variable" data-binding-hash="17358108296605513516" style="color: hsl(331,46%,60%);">x</span>.to_string();
|
||||
}
|
||||
|
||||
<span class="keyword">fn</span> <span class="function">bar</span>() {
|
||||
|
|
|
@ -20,13 +20,13 @@ pub mod tags {
|
|||
pub(crate) const FIELD: &str = "field";
|
||||
pub(crate) const FUNCTION: &str = "function";
|
||||
pub(crate) const MODULE: &str = "module";
|
||||
pub(crate) const TYPE: &str = "type";
|
||||
pub(crate) const CONSTANT: &str = "constant";
|
||||
pub(crate) const MACRO: &str = "macro";
|
||||
|
||||
pub(crate) const VARIABLE: &str = "variable";
|
||||
pub(crate) const VARIABLE_MUT: &str = "variable.mut";
|
||||
pub(crate) const TEXT: &str = "text";
|
||||
|
||||
pub(crate) const TYPE: &str = "type";
|
||||
pub(crate) const TYPE_BUILTIN: &str = "type.builtin";
|
||||
pub(crate) const TYPE_SELF: &str = "type.self";
|
||||
pub(crate) const TYPE_PARAM: &str = "type.param";
|
||||
|
@ -35,13 +35,14 @@ pub mod tags {
|
|||
pub(crate) const LITERAL_BYTE: &str = "literal.byte";
|
||||
pub(crate) const LITERAL_NUMERIC: &str = "literal.numeric";
|
||||
pub(crate) const LITERAL_CHAR: &str = "literal.char";
|
||||
|
||||
pub(crate) const LITERAL_COMMENT: &str = "comment";
|
||||
pub(crate) const LITERAL_STRING: &str = "string";
|
||||
pub(crate) const LITERAL_ATTRIBUTE: &str = "attribute";
|
||||
|
||||
pub(crate) const KEYWORD: &str = "keyword";
|
||||
pub(crate) const KEYWORD_UNSAFE: &str = "keyword.unsafe";
|
||||
pub(crate) const KEYWORD_CONTROL: &str = "keyword.control";
|
||||
pub(crate) const KEYWORD: &str = "keyword";
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -109,15 +110,21 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
|
|||
let name_ref = node.as_node().cloned().and_then(ast::NameRef::cast).unwrap();
|
||||
let name_kind =
|
||||
classify_name_ref(db, InFile::new(file_id.into(), &name_ref)).map(|d| d.kind);
|
||||
match name_kind {
|
||||
Some(name_kind) => {
|
||||
if let Local(local) = &name_kind {
|
||||
if let Some(name) = local.name(db) {
|
||||
let shadow_count =
|
||||
bindings_shadow_count.entry(name.clone()).or_default();
|
||||
binding_hash =
|
||||
Some(calc_binding_hash(file_id, &name, *shadow_count))
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(Local(local)) = &name_kind {
|
||||
if let Some(name) = local.name(db) {
|
||||
let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
|
||||
binding_hash = Some(calc_binding_hash(file_id, &name, *shadow_count))
|
||||
highlight_name(db, name_kind)
|
||||
}
|
||||
};
|
||||
|
||||
name_kind.map_or(tags::TEXT, |it| highlight_name(db, it))
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
NAME => {
|
||||
let name = node.as_node().cloned().and_then(ast::Name::cast).unwrap();
|
||||
|
|
123
editors/code/src/color_theme.ts
Normal file
123
editors/code/src/color_theme.ts
Normal file
|
@ -0,0 +1,123 @@
|
|||
import * as fs from 'fs';
|
||||
import * as jsonc from 'jsonc-parser';
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export interface TextMateRuleSettings {
|
||||
foreground?: string;
|
||||
background?: string;
|
||||
fontStyle?: string;
|
||||
}
|
||||
|
||||
export class ColorTheme {
|
||||
private rules: Map<string, TextMateRuleSettings> = new Map();
|
||||
|
||||
static load(): ColorTheme {
|
||||
// Find out current color theme
|
||||
const themeName = vscode.workspace
|
||||
.getConfiguration('workbench')
|
||||
.get('colorTheme');
|
||||
|
||||
if (typeof themeName !== 'string') {
|
||||
// console.warn('workbench.colorTheme is', themeName)
|
||||
return new ColorTheme();
|
||||
}
|
||||
return loadThemeNamed(themeName);
|
||||
}
|
||||
|
||||
static fromRules(rules: TextMateRule[]): ColorTheme {
|
||||
const res = new ColorTheme();
|
||||
for (const rule of rules) {
|
||||
const scopes = typeof rule.scope === 'string'
|
||||
? [rule.scope]
|
||||
: rule.scope;
|
||||
for (const scope of scopes) {
|
||||
res.rules.set(scope, rule.settings)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
lookup(scopes: string[]): TextMateRuleSettings {
|
||||
let res: TextMateRuleSettings = {}
|
||||
for (const scope of scopes) {
|
||||
this.rules.forEach((value, key) => {
|
||||
if (scope.startsWith(key)) {
|
||||
res = mergeRuleSettings(res, value)
|
||||
}
|
||||
})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
mergeFrom(other: ColorTheme) {
|
||||
other.rules.forEach((value, key) => {
|
||||
const merged = mergeRuleSettings(this.rules.get(key), value)
|
||||
this.rules.set(key, merged)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function loadThemeNamed(themeName: string): ColorTheme {
|
||||
function isTheme(extension: vscode.Extension<any>): boolean {
|
||||
return (
|
||||
extension.extensionKind === vscode.ExtensionKind.UI &&
|
||||
extension.packageJSON.contributes &&
|
||||
extension.packageJSON.contributes.themes
|
||||
);
|
||||
}
|
||||
|
||||
let themePaths = vscode.extensions.all
|
||||
.filter(isTheme)
|
||||
.flatMap(ext => {
|
||||
return ext.packageJSON.contributes.themes
|
||||
.filter((it: any) => (it.id || it.label) === themeName)
|
||||
.map((it: any) => path.join(ext.extensionPath, it.path));
|
||||
})
|
||||
|
||||
const res = new ColorTheme();
|
||||
for (const themePath of themePaths) {
|
||||
res.mergeFrom(loadThemeFile(themePath))
|
||||
}
|
||||
|
||||
const customizations: any = vscode.workspace.getConfiguration('editor').get('tokenColorCustomizations');
|
||||
res.mergeFrom(ColorTheme.fromRules(customizations?.textMateRules ?? []))
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
function loadThemeFile(themePath: string): ColorTheme {
|
||||
let text;
|
||||
try {
|
||||
text = fs.readFileSync(themePath, 'utf8')
|
||||
} catch {
|
||||
return new ColorTheme();
|
||||
}
|
||||
const obj = jsonc.parse(text);
|
||||
const tokenColors = obj?.tokenColors ?? [];
|
||||
const res = ColorTheme.fromRules(tokenColors);
|
||||
|
||||
for (const include in obj?.include ?? []) {
|
||||
const includePath = path.join(path.dirname(themePath), include);
|
||||
const tmp = loadThemeFile(includePath);
|
||||
res.mergeFrom(tmp);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
interface TextMateRule {
|
||||
scope: string | string[];
|
||||
settings: TextMateRuleSettings;
|
||||
}
|
||||
|
||||
function mergeRuleSettings(
|
||||
defaultSetting: TextMateRuleSettings | undefined,
|
||||
override: TextMateRuleSettings,
|
||||
): TextMateRuleSettings {
|
||||
return {
|
||||
foreground: override.foreground ?? defaultSetting?.foreground,
|
||||
background: override.background ?? defaultSetting?.background,
|
||||
fontStyle: override.fontStyle ?? defaultSetting?.fontStyle,
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as scopesMapper from './scopes_mapper';
|
||||
|
||||
const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG;
|
||||
|
||||
|
@ -58,9 +57,6 @@ export class Config {
|
|||
|
||||
if (config.has('highlightingOn')) {
|
||||
this.highlightingOn = config.get('highlightingOn') as boolean;
|
||||
if (this.highlightingOn) {
|
||||
scopesMapper.load();
|
||||
}
|
||||
}
|
||||
|
||||
if (config.has('rainbowHighlightingOn')) {
|
||||
|
|
|
@ -3,8 +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 { loadThemeColors, TextMateRuleSettings } from './scopes';
|
||||
import * as scopesMapper from './scopes_mapper';
|
||||
import { ColorTheme, TextMateRuleSettings } from './color_theme';
|
||||
|
||||
import { Ctx } from './ctx';
|
||||
|
||||
|
@ -168,69 +167,16 @@ class Highlighter {
|
|||
}
|
||||
}
|
||||
|
||||
function initDecorations(): Map<
|
||||
string,
|
||||
vscode.TextEditorDecorationType
|
||||
> {
|
||||
const themeColors = loadThemeColors();
|
||||
|
||||
const decoration = (
|
||||
tag: string,
|
||||
textDecoration?: string,
|
||||
): [string, vscode.TextEditorDecorationType] => {
|
||||
const rule = scopesMapper.toRule(tag, it => themeColors.get(it));
|
||||
|
||||
if (rule) {
|
||||
const decor = createDecorationFromTextmate(rule);
|
||||
return [tag, decor];
|
||||
} else {
|
||||
const fallBackTag = 'ralsp.' + tag;
|
||||
// console.log(' ');
|
||||
// console.log('Missing theme for: <"' + tag + '"> for following mapped scopes:');
|
||||
// console.log(scopesMapper.find(tag));
|
||||
// console.log('Falling back to values defined in: ' + fallBackTag);
|
||||
// console.log(' ');
|
||||
const color = new vscode.ThemeColor(fallBackTag);
|
||||
const decor = vscode.window.createTextEditorDecorationType({
|
||||
color,
|
||||
textDecoration,
|
||||
});
|
||||
return [tag, decor];
|
||||
}
|
||||
};
|
||||
|
||||
const decorations: Iterable<[
|
||||
string,
|
||||
vscode.TextEditorDecorationType,
|
||||
]> = [
|
||||
decoration('comment'),
|
||||
decoration('string'),
|
||||
decoration('keyword'),
|
||||
decoration('keyword.control'),
|
||||
decoration('keyword.unsafe'),
|
||||
decoration('function'),
|
||||
decoration('parameter'),
|
||||
decoration('constant'),
|
||||
decoration('type.builtin'),
|
||||
decoration('type.generic'),
|
||||
decoration('type.lifetime'),
|
||||
decoration('type.param'),
|
||||
decoration('type.self'),
|
||||
decoration('type'),
|
||||
decoration('text'),
|
||||
decoration('attribute'),
|
||||
decoration('literal'),
|
||||
decoration('literal.numeric'),
|
||||
decoration('literal.char'),
|
||||
decoration('literal.byte'),
|
||||
decoration('macro'),
|
||||
decoration('variable'),
|
||||
decoration('variable.mut', 'underline'),
|
||||
decoration('field'),
|
||||
decoration('module'),
|
||||
];
|
||||
|
||||
return new Map<string, vscode.TextEditorDecorationType>(decorations);
|
||||
function initDecorations(): Map<string, vscode.TextEditorDecorationType> {
|
||||
const theme = ColorTheme.load();
|
||||
const res = new Map()
|
||||
TAG_TO_SCOPES.forEach((scopes, tag) => {
|
||||
if (!scopes) throw `unmapped tag: ${tag}`
|
||||
let rule = theme.lookup(scopes)
|
||||
const decor = createDecorationFromTextmate(rule);
|
||||
res.set(tag, decor)
|
||||
})
|
||||
return res;
|
||||
}
|
||||
|
||||
function createDecorationFromTextmate(
|
||||
|
@ -267,3 +213,33 @@ function createDecorationFromTextmate(
|
|||
}
|
||||
return vscode.window.createTextEditorDecorationType(decorationOptions);
|
||||
}
|
||||
|
||||
// sync with tags from `syntax_highlighting.rs`.
|
||||
const TAG_TO_SCOPES = new Map<string, string[]>([
|
||||
["field", ["entity.name.field"]],
|
||||
["function", ["entity.name.function"]],
|
||||
["module", ["entity.name.module"]],
|
||||
["constant", ["entity.name.constant"]],
|
||||
["macro", ["entity.name.macro"]],
|
||||
|
||||
["variable", ["variable"]],
|
||||
["variable.mut", ["variable", "meta.mutable"]],
|
||||
|
||||
["type", ["entity.name.type"]],
|
||||
["type.builtin", ["entity.name.type", "support.type.primitive"]],
|
||||
["type.self", ["entity.name.type.parameter.self"]],
|
||||
["type.param", ["entity.name.type.parameter"]],
|
||||
["type.lifetime", ["entity.name.type.lifetime"]],
|
||||
|
||||
["literal.byte", ["constant.character.byte"]],
|
||||
["literal.char", ["constant.character"]],
|
||||
["literal.numeric", ["constant.numeric"]],
|
||||
|
||||
["comment", ["comment"]],
|
||||
["string", ["string.quoted"]],
|
||||
["attribute", ["meta.attribute"]],
|
||||
|
||||
["keyword", ["keyword"]],
|
||||
["keyword.unsafe", ["keyword.other.unsafe"]],
|
||||
["keyword.control", ["keyword.control"]],
|
||||
]);
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
import * as fs from 'fs';
|
||||
import * as jsonc from 'jsonc-parser';
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export interface TextMateRuleSettings {
|
||||
foreground?: string;
|
||||
background?: string;
|
||||
fontStyle?: string;
|
||||
}
|
||||
|
||||
// Load all textmate scopes in the currently active theme
|
||||
export function loadThemeColors(): Map<string, TextMateRuleSettings> {
|
||||
// Find out current color theme
|
||||
const themeName = vscode.workspace
|
||||
.getConfiguration('workbench')
|
||||
.get('colorTheme');
|
||||
|
||||
if (typeof themeName !== 'string') {
|
||||
// console.warn('workbench.colorTheme is', themeName)
|
||||
return new Map();
|
||||
}
|
||||
return loadThemeNamed(themeName);
|
||||
}
|
||||
|
||||
function loadThemeNamed(themeName: string): Map<string, TextMateRuleSettings> {
|
||||
function isTheme(extension: vscode.Extension<any>): boolean {
|
||||
return (
|
||||
extension.extensionKind === vscode.ExtensionKind.UI &&
|
||||
extension.packageJSON.contributes &&
|
||||
extension.packageJSON.contributes.themes
|
||||
);
|
||||
}
|
||||
|
||||
let themePaths = vscode.extensions.all
|
||||
.filter(isTheme)
|
||||
.flatMap(ext => {
|
||||
return ext.packageJSON.contributes.themes
|
||||
.filter((it: any) => (it.id || it.label) === themeName)
|
||||
.map((it: any) => path.join(ext.extensionPath, it.path));
|
||||
})
|
||||
|
||||
const res = new Map();
|
||||
for (const themePath of themePaths) {
|
||||
mergeInto(res, loadThemeFile(themePath))
|
||||
}
|
||||
|
||||
const customizations: any = vscode.workspace.getConfiguration('editor').get('tokenColorCustomizations');
|
||||
mergeInto(res, loadColors(customizations?.textMateRules ?? []))
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
for (const include in obj?.include ?? []) {
|
||||
const includePath = path.join(path.dirname(themePath), include);
|
||||
const tmp = loadThemeFile(includePath);
|
||||
mergeInto(res, tmp);
|
||||
}
|
||||
|
||||
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 {
|
||||
return {
|
||||
foreground: defaultSetting?.foreground ?? override.foreground,
|
||||
background: defaultSetting?.background ?? override.background,
|
||||
fontStyle: defaultSetting?.fontStyle ?? override.fontStyle,
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
})
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
import * as vscode from 'vscode';
|
||||
import { TextMateRuleSettings } from './scopes';
|
||||
|
||||
let mappings = new Map<string, string[]>();
|
||||
|
||||
const defaultMapping = new Map<string, string[]>([
|
||||
[
|
||||
'comment',
|
||||
[
|
||||
'comment',
|
||||
'comment.block',
|
||||
'comment.line',
|
||||
'comment.block.documentation',
|
||||
],
|
||||
],
|
||||
['string', ['string']],
|
||||
['keyword', ['keyword']],
|
||||
['keyword.control', ['keyword.control', 'keyword', 'keyword.other']],
|
||||
[
|
||||
'keyword.unsafe',
|
||||
['storage.modifier', 'keyword.other', 'keyword.control', 'keyword'],
|
||||
],
|
||||
['function', ['entity.name.function']],
|
||||
['parameter', ['variable.parameter']],
|
||||
['constant', ['constant', 'variable']],
|
||||
['type', ['entity.name.type']],
|
||||
['builtin', ['variable.language', 'support.type', 'support.type']],
|
||||
['text', ['string', 'string.quoted', 'string.regexp']],
|
||||
['attribute', ['keyword']],
|
||||
['literal', ['string', 'string.quoted', 'string.regexp']],
|
||||
['macro', ['entity.name.function', 'keyword.other', 'entity.name.macro']],
|
||||
['variable', ['variable']],
|
||||
['variable.mut', ['variable', 'storage.modifier']],
|
||||
[
|
||||
'field',
|
||||
[
|
||||
'variable.object.property',
|
||||
'meta.field.declaration',
|
||||
'meta.definition.property',
|
||||
'variable.other',
|
||||
],
|
||||
],
|
||||
['module', ['entity.name.section', 'entity.other']],
|
||||
]);
|
||||
|
||||
export function find(scope: string): string[] {
|
||||
return mappings.get(scope) || [];
|
||||
}
|
||||
|
||||
export function toRule(
|
||||
scope: string,
|
||||
intoRule: (scope: string) => TextMateRuleSettings | undefined,
|
||||
): TextMateRuleSettings | undefined {
|
||||
return find(scope)
|
||||
.map(intoRule)
|
||||
.filter(rule => rule !== undefined)[0];
|
||||
}
|
||||
|
||||
function isString(value: any): value is string {
|
||||
return typeof value === 'string';
|
||||
}
|
||||
|
||||
function isArrayOfString(value: any): value is string[] {
|
||||
return Array.isArray(value) && value.every(item => isString(item));
|
||||
}
|
||||
|
||||
export function load() {
|
||||
const rawConfig: { [key: string]: any } =
|
||||
vscode.workspace
|
||||
.getConfiguration('rust-analyzer')
|
||||
.get('scopeMappings') || {};
|
||||
|
||||
mappings = Object.entries(rawConfig)
|
||||
.filter(([_, value]) => isString(value) || isArrayOfString(value))
|
||||
.reduce((list, [key, value]: [string, string | string[]]) => {
|
||||
return list.set(key, isString(value) ? [value] : value);
|
||||
}, defaultMapping);
|
||||
}
|
Loading…
Reference in a new issue