aboutsummaryrefslogtreecommitdiff
path: root/code/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-07-30 19:58:49 +0100
committerAleksey Kladov <[email protected]>2018-07-30 19:58:49 +0100
commitac0d8c48f7a277d4a43448fe7dd4279383bc53f0 (patch)
tree5fe6d1f761f15d1e2d63fc4e9be0c16e2f0b3d93 /code/src
parent6fc66c4ee667da871ea1f0c8b48b5e9b7373a187 (diff)
JS plugin
Diffstat (limited to 'code/src')
-rw-r--r--code/src/main.ts193
1 files changed, 193 insertions, 0 deletions
diff --git a/code/src/main.ts b/code/src/main.ts
new file mode 100644
index 000000000..dfb005c09
--- /dev/null
+++ b/code/src/main.ts
@@ -0,0 +1,193 @@
1'use strict'
2import * as vscode from 'vscode'
3
4const backend = require("../../native")
5
6let docToSyntax;
7
8let uris = {
9 syntaxTree: vscode.Uri.parse('libsyntax-rust://syntaxtree')
10}
11
12
13export function activate(context: vscode.ExtensionContext) {
14 let textDocumentContentProvider = new TextDocumentContentProvider()
15
16 let dispose = (disposable) => {
17 context.subscriptions.push(disposable);
18 }
19
20 let registerCommand = (name, f) => {
21 dispose(vscode.commands.registerCommand(name, f))
22 }
23
24 docToSyntax = documentToFile(context.subscriptions, () => {
25 let emitter = textDocumentContentProvider.eventEmitter
26 emitter.fire(uris.syntaxTree)
27 let syntax = activeSyntax()
28 console.log(syntax.highlight());
29 setHighlights(vscode.window.activeTextEditor, syntax.highlight())
30 })
31
32
33 dispose(vscode.workspace.registerTextDocumentContentProvider(
34 'libsyntax-rust',
35 textDocumentContentProvider
36 ))
37
38 registerCommand('libsyntax-rust.syntaxTree', () => openDoc(uris.syntaxTree))
39}
40
41export function deactivate() { }
42
43export class Syntax {
44 imp;
45 doc: vscode.TextDocument;
46
47 constructor(imp, doc: vscode.TextDocument) {
48 this.imp = imp
49 this.doc = doc
50 }
51
52 syntaxTree(): string { return this.imp.syntaxTree() }
53 highlight(): Array<[number, number, string]> { return this.imp.highlight() }
54}
55
56
57function activeDoc() {
58 return vscode.window.activeTextEditor.document
59}
60
61function activeSyntax(): Syntax {
62 let doc = activeDoc()
63 if (doc == null) return null
64 return docToSyntax(doc)
65}
66
67async function openDoc(uri: vscode.Uri) {
68 let document = await vscode.workspace.openTextDocument(uri)
69 return vscode.window.showTextDocument(document, vscode.ViewColumn.Two, true)
70}
71
72function documentToFile(disposables: vscode.Disposable[], onChange) {
73 let docs = {}
74 function update(doc: vscode.TextDocument, file) {
75 let key = doc.uri.toString()
76 if (file == null) {
77 delete docs[key]
78 } else {
79 docs[key] = file
80 }
81 onChange(doc)
82 }
83 function get(doc: vscode.TextDocument) {
84 return docs[doc.uri.toString()]
85 }
86
87 function isKnownDoc(doc: vscode.TextDocument) {
88 return doc.fileName.endsWith('.rs')
89 }
90
91 function createFile(text: String) {
92 return new backend.RustFile(text)
93 }
94
95 vscode.workspace.onDidChangeTextDocument((event: vscode.TextDocumentChangeEvent) => {
96 let doc = event.document
97 if (!isKnownDoc(event.document)) return
98 update(doc, null)
99 }, null, disposables)
100
101 vscode.workspace.onDidOpenTextDocument((doc: vscode.TextDocument) => {
102 if (!isKnownDoc(doc)) return
103 update(doc, createFile(doc.getText()))
104 }, null, disposables)
105
106 vscode.workspace.onDidCloseTextDocument((doc: vscode.TextDocument) => {
107 update(doc, null)
108 }, null, disposables)
109
110 return (doc: vscode.TextDocument) => {
111 if (!isKnownDoc(doc)) return null
112
113 if (!get(doc)) {
114 update(doc, createFile(doc.getText()))
115 }
116 let imp = get(doc)
117 return new Syntax(imp, doc)
118 }
119}
120
121export class TextDocumentContentProvider implements vscode.TextDocumentContentProvider {
122 public eventEmitter = new vscode.EventEmitter<vscode.Uri>()
123 public syntaxTree: string = "Not available"
124
125 public provideTextDocumentContent(uri: vscode.Uri): vscode.ProviderResult<string> {
126 let syntax = activeSyntax()
127 if (syntax == null) return
128 if (uri.toString() == uris.syntaxTree.toString()) {
129 return syntax.syntaxTree()
130 }
131 }
132
133 get onDidChange(): vscode.Event<vscode.Uri> {
134 return this.eventEmitter.event
135 }
136}
137
138const decorations = (() => {
139 const decor = (obj) => vscode.window.createTextEditorDecorationType({ color: obj })
140 return {
141 background: decor("#3F3F3F"),
142 error: vscode.window.createTextEditorDecorationType({
143 borderColor: "red",
144 borderStyle: "none none dashed none",
145 }),
146 comment: decor("#7F9F7F"),
147 string: decor("#CC9393"),
148 keyword: decor("#F0DFAF"),
149 function: decor("#93E0E3"),
150 parameter: decor("#94BFF3"),
151 builtin: decor("#DD6718"),
152 text: decor("#DCDCCC"),
153 attribute: decor("#BFEBBF"),
154 literal: decor("#DFAF8F"),
155 }
156})()
157
158function setHighlights(
159 editor: vscode.TextEditor,
160 highlihgs: Array<[number, number, string]>
161) {
162 console.log("setHighlight");
163 let byTag = {}
164 for (let tag in decorations) {
165 byTag[tag] = []
166 }
167
168 for (let [start, end, tag] of highlihgs) {
169 if (!byTag[tag]) {
170 console.log(`unknown tag ${tag}`)
171 continue
172 }
173 let range = toVsRange(editor.document, [start, end])
174 byTag[tag].push(range)
175 }
176
177 for (let tag in byTag) {
178 let dec = decorations[tag]
179 let ranges = byTag[tag]
180 editor.setDecorations(dec, ranges)
181 }
182}
183
184export function toVsRange(doc: vscode.TextDocument, range: [number, number]): vscode.Range {
185 return new vscode.Range(
186 doc.positionAt(range[0]),
187 doc.positionAt(range[1]),
188 )
189}
190
191function fromVsRange(doc: vscode.TextDocument, range: vscode.Range): [number, number] {
192 return [doc.offsetAt(range.start), doc.offsetAt(range.end)]
193}