diff options
Diffstat (limited to 'editors/code/src/highlighting.ts')
-rw-r--r-- | editors/code/src/highlighting.ts | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts new file mode 100644 index 000000000..e2ac4d629 --- /dev/null +++ b/editors/code/src/highlighting.ts | |||
@@ -0,0 +1,82 @@ | |||
1 | import * as vscode from 'vscode'; | ||
2 | import * as lc from 'vscode-languageclient'; | ||
3 | |||
4 | import { Server } from './server'; | ||
5 | |||
6 | export interface Decoration { | ||
7 | range: lc.Range; | ||
8 | tag: string; | ||
9 | } | ||
10 | |||
11 | export class Highlighter { | ||
12 | private static initDecorations(): Map<string, vscode.TextEditorDecorationType> { | ||
13 | const decor = (color: string) => vscode.window.createTextEditorDecorationType({ color }); | ||
14 | |||
15 | const decorations: Iterable<[string, vscode.TextEditorDecorationType]> = [ | ||
16 | ['background', decor('#3F3F3F')], | ||
17 | ['error', vscode.window.createTextEditorDecorationType({ | ||
18 | borderColor: 'red', | ||
19 | borderStyle: 'none none dashed none', | ||
20 | })], | ||
21 | ['comment', decor('#7F9F7F')], | ||
22 | ['string', decor('#CC9393')], | ||
23 | ['keyword', decor('#F0DFAF')], | ||
24 | ['function', decor('#93E0E3')], | ||
25 | ['parameter', decor('#94BFF3')], | ||
26 | ['builtin', decor('#DD6718')], | ||
27 | ['text', decor('#DCDCCC')], | ||
28 | ['attribute', decor('#BFEBBF')], | ||
29 | ['literal', decor('#DFAF8F')], | ||
30 | ]; | ||
31 | |||
32 | return new Map<string, vscode.TextEditorDecorationType>(decorations); | ||
33 | } | ||
34 | |||
35 | private decorations: (Map<string, vscode.TextEditorDecorationType> | null) = null; | ||
36 | |||
37 | public removeHighlights() { | ||
38 | if (this.decorations == null) { | ||
39 | return; | ||
40 | } | ||
41 | |||
42 | // Decorations are removed when the object is disposed | ||
43 | for (const decoration of this.decorations.values()) { | ||
44 | decoration.dispose(); | ||
45 | } | ||
46 | |||
47 | this.decorations = null; | ||
48 | } | ||
49 | |||
50 | public setHighlights( | ||
51 | editor: vscode.TextEditor, | ||
52 | highlights: Decoration[], | ||
53 | ) { | ||
54 | // Initialize decorations if necessary | ||
55 | // | ||
56 | // Note: decoration objects need to be kept around so we can dispose them | ||
57 | // if the user disables syntax highlighting | ||
58 | if (this.decorations == null) { | ||
59 | this.decorations = Highlighter.initDecorations(); | ||
60 | } | ||
61 | |||
62 | const byTag: Map<string, vscode.Range[]> = new Map(); | ||
63 | for (const tag of this.decorations.keys()) { | ||
64 | byTag.set(tag, []); | ||
65 | } | ||
66 | |||
67 | for (const d of highlights) { | ||
68 | if (!byTag.get(d.tag)) { | ||
69 | continue; | ||
70 | } | ||
71 | byTag.get(d.tag)!.push( | ||
72 | Server.client.protocol2CodeConverter.asRange(d.range), | ||
73 | ); | ||
74 | } | ||
75 | |||
76 | for (const tag of byTag.keys()) { | ||
77 | const dec = this.decorations.get(tag) as vscode.TextEditorDecorationType; | ||
78 | const ranges = byTag.get(tag)!; | ||
79 | editor.setDecorations(dec, ranges); | ||
80 | } | ||
81 | } | ||
82 | } | ||