aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src/highlighting.ts
diff options
context:
space:
mode:
Diffstat (limited to 'editors/code/src/highlighting.ts')
-rw-r--r--editors/code/src/highlighting.ts215
1 files changed, 108 insertions, 107 deletions
diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts
index 247673b5c..5e9cbe0de 100644
--- a/editors/code/src/highlighting.ts
+++ b/editors/code/src/highlighting.ts
@@ -3,7 +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 * as scopes from './scopes'; 6import { loadThemeColors, TextMateRuleSettings } from './scopes';
7import * as scopesMapper from './scopes_mapper'; 7import * as scopesMapper from './scopes_mapper';
8 8
9import { Ctx } from './ctx'; 9import { Ctx } from './ctx';
@@ -47,7 +47,7 @@ export function activateHighlighting(ctx: Ctx) {
47 const params: lc.TextDocumentIdentifier = { 47 const params: lc.TextDocumentIdentifier = {
48 uri: editor.document.uri.toString(), 48 uri: editor.document.uri.toString(),
49 }; 49 };
50 const decorations = await ctx.client.sendRequest<Decoration[]>( 50 const decorations = await ctx.sendRequestWithRetry<Decoration[]>(
51 'rust-analyzer/decorationsRequest', 51 'rust-analyzer/decorationsRequest',
52 params, 52 params,
53 ); 53 );
@@ -62,7 +62,7 @@ interface PublishDecorationsParams {
62 decorations: Decoration[]; 62 decorations: Decoration[];
63} 63}
64 64
65export interface Decoration { 65interface Decoration {
66 range: lc.Range; 66 range: lc.Range;
67 tag: string; 67 tag: string;
68 bindingHash?: string; 68 bindingHash?: string;
@@ -81,116 +81,17 @@ function fancify(seed: string, shade: 'light' | 'dark') {
81 return `hsl(${h},${s}%,${l}%)`; 81 return `hsl(${h},${s}%,${l}%)`;
82} 82}
83 83
84function createDecorationFromTextmate(
85 themeStyle: scopes.TextMateRuleSettings,
86): vscode.TextEditorDecorationType {
87 const decorationOptions: vscode.DecorationRenderOptions = {};
88 decorationOptions.rangeBehavior = vscode.DecorationRangeBehavior.OpenOpen;
89
90 if (themeStyle.foreground) {
91 decorationOptions.color = themeStyle.foreground;
92 }
93
94 if (themeStyle.background) {
95 decorationOptions.backgroundColor = themeStyle.background;
96 }
97
98 if (themeStyle.fontStyle) {
99 const parts: string[] = themeStyle.fontStyle.split(' ');
100 parts.forEach(part => {
101 switch (part) {
102 case 'italic':
103 decorationOptions.fontStyle = 'italic';
104 break;
105 case 'bold':
106 decorationOptions.fontWeight = 'bold';
107 break;
108 case 'underline':
109 decorationOptions.textDecoration = 'underline';
110 break;
111 default:
112 break;
113 }
114 });
115 }
116 return vscode.window.createTextEditorDecorationType(decorationOptions);
117}
118
119class Highlighter { 84class Highlighter {
120 private ctx: Ctx; 85 private ctx: Ctx;
121
122 constructor(ctx: Ctx) {
123 this.ctx = ctx;
124 }
125
126 private static initDecorations(): Map<
127 string,
128 vscode.TextEditorDecorationType
129 > {
130 const decoration = (
131 tag: string,
132 textDecoration?: string,
133 ): [string, vscode.TextEditorDecorationType] => {
134 const rule = scopesMapper.toRule(tag, scopes.find);
135
136 if (rule) {
137 const decor = createDecorationFromTextmate(rule);
138 return [tag, decor];
139 } else {
140 const fallBackTag = 'ralsp.' + tag;
141 // console.log(' ');
142 // console.log('Missing theme for: <"' + tag + '"> for following mapped scopes:');
143 // console.log(scopesMapper.find(tag));
144 // console.log('Falling back to values defined in: ' + fallBackTag);
145 // console.log(' ');
146 const color = new vscode.ThemeColor(fallBackTag);
147 const decor = vscode.window.createTextEditorDecorationType({
148 color,
149 textDecoration,
150 });
151 return [tag, decor];
152 }
153 };
154
155 const decorations: Iterable<[
156 string,
157 vscode.TextEditorDecorationType,
158 ]> = [
159 decoration('comment'),
160 decoration('string'),
161 decoration('keyword'),
162 decoration('keyword.control'),
163 decoration('keyword.unsafe'),
164 decoration('function'),
165 decoration('parameter'),
166 decoration('constant'),
167 decoration('type.builtin'),
168 decoration('type.generic'),
169 decoration('type.lifetime'),
170 decoration('type.param'),
171 decoration('type.self'),
172 decoration('type'),
173 decoration('text'),
174 decoration('attribute'),
175 decoration('literal'),
176 decoration('literal.numeric'),
177 decoration('literal.char'),
178 decoration('literal.byte'),
179 decoration('macro'),
180 decoration('variable'),
181 decoration('variable.mut', 'underline'),
182 decoration('field'),
183 decoration('module'),
184 ];
185
186 return new Map<string, vscode.TextEditorDecorationType>(decorations);
187 }
188
189 private decorations: Map< 86 private decorations: Map<
190 string, 87 string,
191 vscode.TextEditorDecorationType 88 vscode.TextEditorDecorationType
192 > | null = null; 89 > | null = null;
193 90
91 constructor(ctx: Ctx) {
92 this.ctx = ctx;
93 }
94
194 public removeHighlights() { 95 public removeHighlights() {
195 if (this.decorations == null) { 96 if (this.decorations == null) {
196 return; 97 return;
@@ -210,7 +111,7 @@ class Highlighter {
210 // Note: decoration objects need to be kept around so we can dispose them 111 // Note: decoration objects need to be kept around so we can dispose them
211 // if the user disables syntax highlighting 112 // if the user disables syntax highlighting
212 if (this.decorations == null) { 113 if (this.decorations == null) {
213 this.decorations = Highlighter.initDecorations(); 114 this.decorations = initDecorations();
214 } 115 }
215 116
216 const byTag: Map<string, vscode.Range[]> = new Map(); 117 const byTag: Map<string, vscode.Range[]> = new Map();
@@ -266,3 +167,103 @@ class Highlighter {
266 } 167 }
267 } 168 }
268} 169}
170
171function initDecorations(): Map<
172 string,
173 vscode.TextEditorDecorationType
174> {
175 const themeColors = loadThemeColors();
176
177 const decoration = (
178 tag: string,
179 textDecoration?: string,
180 ): [string, vscode.TextEditorDecorationType] => {
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}
235
236function createDecorationFromTextmate(
237 themeStyle: TextMateRuleSettings,
238): vscode.TextEditorDecorationType {
239 const decorationOptions: vscode.DecorationRenderOptions = {};
240 decorationOptions.rangeBehavior = vscode.DecorationRangeBehavior.OpenOpen;
241
242 if (themeStyle.foreground) {
243 decorationOptions.color = themeStyle.foreground;
244 }
245
246 if (themeStyle.background) {
247 decorationOptions.backgroundColor = themeStyle.background;
248 }
249
250 if (themeStyle.fontStyle) {
251 const parts: string[] = themeStyle.fontStyle.split(' ');
252 parts.forEach(part => {
253 switch (part) {
254 case 'italic':
255 decorationOptions.fontStyle = 'italic';
256 break;
257 case 'bold':
258 decorationOptions.fontWeight = 'bold';
259 break;
260 case 'underline':
261 decorationOptions.textDecoration = 'underline';
262 break;
263 default:
264 break;
265 }
266 });
267 }
268 return vscode.window.createTextEditorDecorationType(decorationOptions);
269}