aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-12-31 10:06:50 +0000
committerAleksey Kladov <[email protected]>2019-12-31 13:11:25 +0000
commit26bd7a896b4bbc4a2432df47dceff939aac921fa (patch)
treebb62a5d32f3999cd1bc430cef64ce13320f8132b
parent6c1d92d6c56185f88581c73617e647397fc79dd2 (diff)
Drop support for legacy colorization
-rw-r--r--crates/ra_ide/src/snapshots/highlighting.html6
-rw-r--r--crates/ra_ide/src/snapshots/rainbow_highlighting.html6
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs27
-rw-r--r--editors/code/src/color_theme.ts123
-rw-r--r--editors/code/src/config.ts4
-rw-r--r--editors/code/src/highlighting.ts106
-rw-r--r--editors/code/src/load_theme_colors.ts108
-rw-r--r--editors/code/src/scopes_mapper.ts78
8 files changed, 187 insertions, 271 deletions
diff --git a/crates/ra_ide/src/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html
index a097cf8e8..1d130544f 100644
--- a/crates/ra_ide/src/snapshots/highlighting.html
+++ b/crates/ra_ide/src/snapshots/highlighting.html
@@ -38,12 +38,12 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
38<span class="keyword">fn</span> <span class="function">main</span>() { 38<span class="keyword">fn</span> <span class="function">main</span>() {
39 <span class="macro">println</span><span class="macro">!</span>(<span class="string">"Hello, {}!"</span>, <span class="literal.numeric">92</span>); 39 <span class="macro">println</span><span class="macro">!</span>(<span class="string">"Hello, {}!"</span>, <span class="literal.numeric">92</span>);
40 40
41 <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>(); 41 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">vec</span> = Vec::new();
42 <span class="keyword.control">if</span> <span class="keyword">true</span> { 42 <span class="keyword.control">if</span> <span class="keyword">true</span> {
43 <span class="keyword">let</span> <span class="variable">x</span> = <span class="literal.numeric">92</span>; 43 <span class="keyword">let</span> <span class="variable">x</span> = <span class="literal.numeric">92</span>;
44 <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> }); 44 <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> });
45 } 45 }
46 <span class="keyword.unsafe">unsafe</span> { <span class="variable.mut">vec</span>.<span class="text">set_len</span>(<span class="literal.numeric">0</span>); } 46 <span class="keyword.unsafe">unsafe</span> { <span class="variable.mut">vec</span>.set_len(<span class="literal.numeric">0</span>); }
47 47
48 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">x</span> = <span class="literal.numeric">42</span>; 48 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">x</span> = <span class="literal.numeric">42</span>;
49 <span class="keyword">let</span> <span class="variable.mut">y</span> = &<span class="keyword">mut</span> <span class="variable.mut">x</span>; 49 <span class="keyword">let</span> <span class="variable.mut">y</span> = &<span class="keyword">mut</span> <span class="variable.mut">x</span>;
diff --git a/crates/ra_ide/src/snapshots/rainbow_highlighting.html b/crates/ra_ide/src/snapshots/rainbow_highlighting.html
index 110556c09..d90ee8540 100644
--- a/crates/ra_ide/src/snapshots/rainbow_highlighting.html
+++ b/crates/ra_ide/src/snapshots/rainbow_highlighting.html
@@ -25,11 +25,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
25</style> 25</style>
26<pre><code><span class="keyword">fn</span> <span class="function">main</span>() { 26<pre><code><span class="keyword">fn</span> <span class="function">main</span>() {
27 <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>; 27 <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>;
28 <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>(); 28 <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();
29 <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>(); 29 <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();
30 30
31 <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>; 31 <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>;
32 <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>(); 32 <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();
33} 33}
34 34
35<span class="keyword">fn</span> <span class="function">bar</span>() { 35<span class="keyword">fn</span> <span class="function">bar</span>() {
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index 0228ee7e9..56a36f587 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -20,13 +20,13 @@ pub mod tags {
20 pub(crate) const FIELD: &str = "field"; 20 pub(crate) const FIELD: &str = "field";
21 pub(crate) const FUNCTION: &str = "function"; 21 pub(crate) const FUNCTION: &str = "function";
22 pub(crate) const MODULE: &str = "module"; 22 pub(crate) const MODULE: &str = "module";
23 pub(crate) const TYPE: &str = "type";
24 pub(crate) const CONSTANT: &str = "constant"; 23 pub(crate) const CONSTANT: &str = "constant";
25 pub(crate) const MACRO: &str = "macro"; 24 pub(crate) const MACRO: &str = "macro";
25
26 pub(crate) const VARIABLE: &str = "variable"; 26 pub(crate) const VARIABLE: &str = "variable";
27 pub(crate) const VARIABLE_MUT: &str = "variable.mut"; 27 pub(crate) const VARIABLE_MUT: &str = "variable.mut";
28 pub(crate) const TEXT: &str = "text";
29 28
29 pub(crate) const TYPE: &str = "type";
30 pub(crate) const TYPE_BUILTIN: &str = "type.builtin"; 30 pub(crate) const TYPE_BUILTIN: &str = "type.builtin";
31 pub(crate) const TYPE_SELF: &str = "type.self"; 31 pub(crate) const TYPE_SELF: &str = "type.self";
32 pub(crate) const TYPE_PARAM: &str = "type.param"; 32 pub(crate) const TYPE_PARAM: &str = "type.param";
@@ -35,13 +35,14 @@ pub mod tags {
35 pub(crate) const LITERAL_BYTE: &str = "literal.byte"; 35 pub(crate) const LITERAL_BYTE: &str = "literal.byte";
36 pub(crate) const LITERAL_NUMERIC: &str = "literal.numeric"; 36 pub(crate) const LITERAL_NUMERIC: &str = "literal.numeric";
37 pub(crate) const LITERAL_CHAR: &str = "literal.char"; 37 pub(crate) const LITERAL_CHAR: &str = "literal.char";
38
38 pub(crate) const LITERAL_COMMENT: &str = "comment"; 39 pub(crate) const LITERAL_COMMENT: &str = "comment";
39 pub(crate) const LITERAL_STRING: &str = "string"; 40 pub(crate) const LITERAL_STRING: &str = "string";
40 pub(crate) const LITERAL_ATTRIBUTE: &str = "attribute"; 41 pub(crate) const LITERAL_ATTRIBUTE: &str = "attribute";
41 42
43 pub(crate) const KEYWORD: &str = "keyword";
42 pub(crate) const KEYWORD_UNSAFE: &str = "keyword.unsafe"; 44 pub(crate) const KEYWORD_UNSAFE: &str = "keyword.unsafe";
43 pub(crate) const KEYWORD_CONTROL: &str = "keyword.control"; 45 pub(crate) const KEYWORD_CONTROL: &str = "keyword.control";
44 pub(crate) const KEYWORD: &str = "keyword";
45} 46}
46 47
47#[derive(Debug)] 48#[derive(Debug)]
@@ -109,15 +110,21 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
109 let name_ref = node.as_node().cloned().and_then(ast::NameRef::cast).unwrap(); 110 let name_ref = node.as_node().cloned().and_then(ast::NameRef::cast).unwrap();
110 let name_kind = 111 let name_kind =
111 classify_name_ref(db, InFile::new(file_id.into(), &name_ref)).map(|d| d.kind); 112 classify_name_ref(db, InFile::new(file_id.into(), &name_ref)).map(|d| d.kind);
113 match name_kind {
114 Some(name_kind) => {
115 if let Local(local) = &name_kind {
116 if let Some(name) = local.name(db) {
117 let shadow_count =
118 bindings_shadow_count.entry(name.clone()).or_default();
119 binding_hash =
120 Some(calc_binding_hash(file_id, &name, *shadow_count))
121 }
122 };
112 123
113 if let Some(Local(local)) = &name_kind { 124 highlight_name(db, name_kind)
114 if let Some(name) = local.name(db) {
115 let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
116 binding_hash = Some(calc_binding_hash(file_id, &name, *shadow_count))
117 } 125 }
118 }; 126 _ => continue,
119 127 }
120 name_kind.map_or(tags::TEXT, |it| highlight_name(db, it))
121 } 128 }
122 NAME => { 129 NAME => {
123 let name = node.as_node().cloned().and_then(ast::Name::cast).unwrap(); 130 let name = node.as_node().cloned().and_then(ast::Name::cast).unwrap();
diff --git a/editors/code/src/color_theme.ts b/editors/code/src/color_theme.ts
new file mode 100644
index 000000000..1df7eba7a
--- /dev/null
+++ b/editors/code/src/color_theme.ts
@@ -0,0 +1,123 @@
1import * as fs from 'fs';
2import * as jsonc from 'jsonc-parser';
3import * as path from 'path';
4import * as vscode from 'vscode';
5
6export interface TextMateRuleSettings {
7 foreground?: string;
8 background?: string;
9 fontStyle?: string;
10}
11
12export class ColorTheme {
13 private rules: Map<string, TextMateRuleSettings> = new Map();
14
15 static load(): ColorTheme {
16 // Find out current color theme
17 const themeName = vscode.workspace
18 .getConfiguration('workbench')
19 .get('colorTheme');
20
21 if (typeof themeName !== 'string') {
22 // console.warn('workbench.colorTheme is', themeName)
23 return new ColorTheme();
24 }
25 return loadThemeNamed(themeName);
26 }
27
28 static fromRules(rules: TextMateRule[]): ColorTheme {
29 const res = new ColorTheme();
30 for (const rule of rules) {
31 const scopes = typeof rule.scope === 'string'
32 ? [rule.scope]
33 : rule.scope;
34 for (const scope of scopes) {
35 res.rules.set(scope, rule.settings)
36 }
37 }
38 return res
39 }
40
41 lookup(scopes: string[]): TextMateRuleSettings {
42 let res: TextMateRuleSettings = {}
43 for (const scope of scopes) {
44 this.rules.forEach((value, key) => {
45 if (scope.startsWith(key)) {
46 res = mergeRuleSettings(res, value)
47 }
48 })
49 }
50 return res
51 }
52
53 mergeFrom(other: ColorTheme) {
54 other.rules.forEach((value, key) => {
55 const merged = mergeRuleSettings(this.rules.get(key), value)
56 this.rules.set(key, merged)
57 })
58 }
59}
60
61function loadThemeNamed(themeName: string): ColorTheme {
62 function isTheme(extension: vscode.Extension<any>): boolean {
63 return (
64 extension.extensionKind === vscode.ExtensionKind.UI &&
65 extension.packageJSON.contributes &&
66 extension.packageJSON.contributes.themes
67 );
68 }
69
70 let themePaths = vscode.extensions.all
71 .filter(isTheme)
72 .flatMap(ext => {
73 return ext.packageJSON.contributes.themes
74 .filter((it: any) => (it.id || it.label) === themeName)
75 .map((it: any) => path.join(ext.extensionPath, it.path));
76 })
77
78 const res = new ColorTheme();
79 for (const themePath of themePaths) {
80 res.mergeFrom(loadThemeFile(themePath))
81 }
82
83 const customizations: any = vscode.workspace.getConfiguration('editor').get('tokenColorCustomizations');
84 res.mergeFrom(ColorTheme.fromRules(customizations?.textMateRules ?? []))
85
86 return res;
87}
88
89function loadThemeFile(themePath: string): ColorTheme {
90 let text;
91 try {
92 text = fs.readFileSync(themePath, 'utf8')
93 } catch {
94 return new ColorTheme();
95 }
96 const obj = jsonc.parse(text);
97 const tokenColors = obj?.tokenColors ?? [];
98 const res = ColorTheme.fromRules(tokenColors);
99
100 for (const include in obj?.include ?? []) {
101 const includePath = path.join(path.dirname(themePath), include);
102 const tmp = loadThemeFile(includePath);
103 res.mergeFrom(tmp);
104 }
105
106 return res;
107}
108
109interface TextMateRule {
110 scope: string | string[];
111 settings: TextMateRuleSettings;
112}
113
114function mergeRuleSettings(
115 defaultSetting: TextMateRuleSettings | undefined,
116 override: TextMateRuleSettings,
117): TextMateRuleSettings {
118 return {
119 foreground: override.foreground ?? defaultSetting?.foreground,
120 background: override.background ?? defaultSetting?.background,
121 fontStyle: override.fontStyle ?? defaultSetting?.fontStyle,
122 }
123}
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index f63d1ddce..ccb0ee2b7 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 scopesMapper from './scopes_mapper';
3 2
4const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG; 3const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG;
5 4
@@ -58,9 +57,6 @@ export class Config {
58 57
59 if (config.has('highlightingOn')) { 58 if (config.has('highlightingOn')) {
60 this.highlightingOn = config.get('highlightingOn') as boolean; 59 this.highlightingOn = config.get('highlightingOn') as boolean;
61 if (this.highlightingOn) {
62 scopesMapper.load();
63 }
64 } 60 }
65 61
66 if (config.has('rainbowHighlightingOn')) { 62 if (config.has('rainbowHighlightingOn')) {
diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts
index e97eb086a..d383d87ef 100644
--- a/editors/code/src/highlighting.ts
+++ b/editors/code/src/highlighting.ts
@@ -3,8 +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 { loadThemeColors, TextMateRuleSettings } from './load_theme_colors'; 6import { ColorTheme, TextMateRuleSettings } from './color_theme';
7import * as scopesMapper from './scopes_mapper';
8 7
9import { Ctx } from './ctx'; 8import { Ctx } from './ctx';
10 9
@@ -168,69 +167,16 @@ class Highlighter {
168 } 167 }
169} 168}
170 169
171function initDecorations(): Map< 170function initDecorations(): Map<string, vscode.TextEditorDecorationType> {
172 string, 171 const theme = ColorTheme.load();
173 vscode.TextEditorDecorationType 172 const res = new Map()
174> { 173 TAG_TO_SCOPES.forEach((scopes, tag) => {
175 const themeColors = loadThemeColors(); 174 if (!scopes) throw `unmapped tag: ${tag}`
176 175 let rule = theme.lookup(scopes)
177 const decoration = ( 176 const decor = createDecorationFromTextmate(rule);
178 tag: string, 177 res.set(tag, decor)
179 textDecoration?: string, 178 })
180 ): [string, vscode.TextEditorDecorationType] => { 179 return res;
181 const rule = scopesMapper.toRule(tag, it => themeColors.get(it));
182
183 if (rule) {
184 const decor = createDecorationFromTextmate(rule);
185 return [tag, decor];
186 } else {
187 const fallBackTag = 'ralsp.' + tag;
188 // console.log(' ');
189 // console.log('Missing theme for: <"' + tag + '"> for following mapped scopes:');
190 // console.log(scopesMapper.find(tag));
191 // console.log('Falling back to values defined in: ' + fallBackTag);
192 // console.log(' ');
193 const color = new vscode.ThemeColor(fallBackTag);
194 const decor = vscode.window.createTextEditorDecorationType({
195 color,
196 textDecoration,
197 });
198 return [tag, decor];
199 }
200 };
201
202 const decorations: Iterable<[
203 string,
204 vscode.TextEditorDecorationType,
205 ]> = [
206 decoration('comment'),
207 decoration('string'),
208 decoration('keyword'),
209 decoration('keyword.control'),
210 decoration('keyword.unsafe'),
211 decoration('function'),
212 decoration('parameter'),
213 decoration('constant'),
214 decoration('type.builtin'),
215 decoration('type.generic'),
216 decoration('type.lifetime'),
217 decoration('type.param'),
218 decoration('type.self'),
219 decoration('type'),
220 decoration('text'),
221 decoration('attribute'),
222 decoration('literal'),
223 decoration('literal.numeric'),
224 decoration('literal.char'),
225 decoration('literal.byte'),
226 decoration('macro'),
227 decoration('variable'),
228 decoration('variable.mut', 'underline'),
229 decoration('field'),
230 decoration('module'),
231 ];
232
233 return new Map<string, vscode.TextEditorDecorationType>(decorations);
234} 180}
235 181
236function createDecorationFromTextmate( 182function createDecorationFromTextmate(
@@ -267,3 +213,33 @@ function createDecorationFromTextmate(
267 } 213 }
268 return vscode.window.createTextEditorDecorationType(decorationOptions); 214 return vscode.window.createTextEditorDecorationType(decorationOptions);
269} 215}
216
217// sync with tags from `syntax_highlighting.rs`.
218const TAG_TO_SCOPES = new Map<string, string[]>([
219 ["field", ["entity.name.field"]],
220 ["function", ["entity.name.function"]],
221 ["module", ["entity.name.module"]],
222 ["constant", ["entity.name.constant"]],
223 ["macro", ["entity.name.macro"]],
224
225 ["variable", ["variable"]],
226 ["variable.mut", ["variable", "meta.mutable"]],
227
228 ["type", ["entity.name.type"]],
229 ["type.builtin", ["entity.name.type", "support.type.primitive"]],
230 ["type.self", ["entity.name.type.parameter.self"]],
231 ["type.param", ["entity.name.type.parameter"]],
232 ["type.lifetime", ["entity.name.type.lifetime"]],
233
234 ["literal.byte", ["constant.character.byte"]],
235 ["literal.char", ["constant.character"]],
236 ["literal.numeric", ["constant.numeric"]],
237
238 ["comment", ["comment"]],
239 ["string", ["string.quoted"]],
240 ["attribute", ["meta.attribute"]],
241
242 ["keyword", ["keyword"]],
243 ["keyword.unsafe", ["keyword.other.unsafe"]],
244 ["keyword.control", ["keyword.control"]],
245]);
diff --git a/editors/code/src/load_theme_colors.ts b/editors/code/src/load_theme_colors.ts
deleted file mode 100644
index 73fabbf54..000000000
--- a/editors/code/src/load_theme_colors.ts
+++ /dev/null
@@ -1,108 +0,0 @@
1import * as fs from 'fs';
2import * as jsonc from 'jsonc-parser';
3import * as path from 'path';
4import * as vscode from 'vscode';
5
6export interface TextMateRuleSettings {
7 foreground?: string;
8 background?: string;
9 fontStyle?: string;
10}
11
12// Load all textmate scopes in the currently active theme
13export function loadThemeColors(): Map<string, TextMateRuleSettings> {
14 // Find out current color theme
15 const themeName = vscode.workspace
16 .getConfiguration('workbench')
17 .get('colorTheme');
18
19 if (typeof themeName !== 'string') {
20 // console.warn('workbench.colorTheme is', themeName)
21 return new Map();
22 }
23 return loadThemeNamed(themeName);
24}
25
26function loadThemeNamed(themeName: string): Map<string, TextMateRuleSettings> {
27 function isTheme(extension: vscode.Extension<any>): boolean {
28 return (
29 extension.extensionKind === vscode.ExtensionKind.UI &&
30 extension.packageJSON.contributes &&
31 extension.packageJSON.contributes.themes
32 );
33 }
34
35 let themePaths = vscode.extensions.all
36 .filter(isTheme)
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 }
47
48 const customizations: any = vscode.workspace.getConfiguration('editor').get('tokenColorCustomizations');
49 mergeInto(res, loadColors(customizations?.textMateRules ?? []))
50
51 return res;
52}
53
54function 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}
73
74interface TextMateRule {
75 scope: string | string[];
76 settings: TextMateRuleSettings;
77}
78
79function 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
90}
91
92function mergeRuleSettings(
93 defaultSetting: TextMateRuleSettings | undefined,
94 override: TextMateRuleSettings,
95): TextMateRuleSettings {
96 return {
97 foreground: defaultSetting?.foreground ?? override.foreground,
98 background: defaultSetting?.background ?? override.background,
99 fontStyle: defaultSetting?.fontStyle ?? override.fontStyle,
100 }
101}
102
103function 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 })
108}
diff --git a/editors/code/src/scopes_mapper.ts b/editors/code/src/scopes_mapper.ts
deleted file mode 100644
index 1295ab476..000000000
--- a/editors/code/src/scopes_mapper.ts
+++ /dev/null
@@ -1,78 +0,0 @@
1import * as vscode from 'vscode';
2import { TextMateRuleSettings } from './load_theme_colors';
3
4let mappings = new Map<string, string[]>();
5
6const defaultMapping = new Map<string, string[]>([
7 [
8 'comment',
9 [
10 'comment',
11 'comment.block',
12 'comment.line',
13 'comment.block.documentation',
14 ],
15 ],
16 ['string', ['string']],
17 ['keyword', ['keyword']],
18 ['keyword.control', ['keyword.control', 'keyword', 'keyword.other']],
19 [
20 'keyword.unsafe',
21 ['storage.modifier', 'keyword.other', 'keyword.control', 'keyword'],
22 ],
23 ['function', ['entity.name.function']],
24 ['parameter', ['variable.parameter']],
25 ['constant', ['constant', 'variable']],
26 ['type', ['entity.name.type']],
27 ['builtin', ['variable.language', 'support.type', 'support.type']],
28 ['text', ['string', 'string.quoted', 'string.regexp']],
29 ['attribute', ['keyword']],
30 ['literal', ['string', 'string.quoted', 'string.regexp']],
31 ['macro', ['entity.name.function', 'keyword.other', 'entity.name.macro']],
32 ['variable', ['variable']],
33 ['variable.mut', ['variable', 'storage.modifier']],
34 [
35 'field',
36 [
37 'variable.object.property',
38 'meta.field.declaration',
39 'meta.definition.property',
40 'variable.other',
41 ],
42 ],
43 ['module', ['entity.name.section', 'entity.other']],
44]);
45
46export function find(scope: string): string[] {
47 return mappings.get(scope) || [];
48}
49
50export function toRule(
51 scope: string,
52 intoRule: (scope: string) => TextMateRuleSettings | undefined,
53): TextMateRuleSettings | undefined {
54 return find(scope)
55 .map(intoRule)
56 .filter(rule => rule !== undefined)[0];
57}
58
59function isString(value: any): value is string {
60 return typeof value === 'string';
61}
62
63function isArrayOfString(value: any): value is string[] {
64 return Array.isArray(value) && value.every(item => isString(item));
65}
66
67export function load() {
68 const rawConfig: { [key: string]: any } =
69 vscode.workspace
70 .getConfiguration('rust-analyzer')
71 .get('scopeMappings') || {};
72
73 mappings = Object.entries(rawConfig)
74 .filter(([_, value]) => isString(value) || isArrayOfString(value))
75 .reduce((list, [key, value]: [string, string | string[]]) => {
76 return list.set(key, isString(value) ? [value] : value);
77 }, defaultMapping);
78}