diff options
Diffstat (limited to 'editors/code/src/highlighting.ts')
-rw-r--r-- | editors/code/src/highlighting.ts | 215 |
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'; | |||
3 | import * as seedrandom_ from 'seedrandom'; | 3 | import * as seedrandom_ from 'seedrandom'; |
4 | const seedrandom = seedrandom_; // https://github.com/jvandemo/generator-angular2-library/issues/221#issuecomment-355945207 | 4 | const seedrandom = seedrandom_; // https://github.com/jvandemo/generator-angular2-library/issues/221#issuecomment-355945207 |
5 | 5 | ||
6 | import * as scopes from './scopes'; | 6 | import { loadThemeColors, TextMateRuleSettings } from './scopes'; |
7 | import * as scopesMapper from './scopes_mapper'; | 7 | import * as scopesMapper from './scopes_mapper'; |
8 | 8 | ||
9 | import { Ctx } from './ctx'; | 9 | import { 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 | ||
65 | export interface Decoration { | 65 | interface 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 | ||
84 | function 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 | |||
119 | class Highlighter { | 84 | class 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 | |||
171 | function 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 | |||
236 | function 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 | } | ||