From f99551f46b1583ed43751e4d26fe76a0b913eb5f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 11 Aug 2018 01:04:09 +0300 Subject: reorganize --- code/src/extension.ts | 194 ++++++++++++++++++++++++++++++++++++++++++++++ code/src/main.ts | 208 -------------------------------------------------- 2 files changed, 194 insertions(+), 208 deletions(-) create mode 100644 code/src/extension.ts delete mode 100644 code/src/main.ts (limited to 'code/src') diff --git a/code/src/extension.ts b/code/src/extension.ts new file mode 100644 index 000000000..bdad1568a --- /dev/null +++ b/code/src/extension.ts @@ -0,0 +1,194 @@ +'use strict'; +import * as vscode from 'vscode'; +import * as lc from 'vscode-languageclient' + + +let client: lc.LanguageClient; + +let uris = { + syntaxTree: vscode.Uri.parse('libsyntax-rust://syntaxtree') +} + + +export function activate(context: vscode.ExtensionContext) { + let textDocumentContentProvider = new TextDocumentContentProvider() + let dispose = (disposable) => { + context.subscriptions.push(disposable); + } + let registerCommand = (name, f) => { + dispose(vscode.commands.registerCommand(name, f)) + } + + registerCommand('libsyntax-rust.syntaxTree', () => openDoc(uris.syntaxTree)) + registerCommand('libsyntax-rust.extendSelection', async () => { + let editor = vscode.window.activeTextEditor + if (editor == null || editor.document.languageId != "rust") return + let request: ExtendSelectionParams = { + textDocument: { uri: editor.document.uri.toString() }, + selections: editor.selections.map((s) => { + return { start: s.start, end: s.end }; + }) + } + let response = await client.sendRequest("m/extendSelection", request) + editor.selections = response.selections.map((range) => { + return new vscode.Selection( + new vscode.Position(range.start.line, range.start.character), + new vscode.Position(range.end.line, range.end.character), + ) + }) + }) + + dispose(vscode.workspace.registerTextDocumentContentProvider( + 'libsyntax-rust', + textDocumentContentProvider + )) + startServer() + vscode.workspace.onDidChangeTextDocument((event: vscode.TextDocumentChangeEvent) => { + let doc = event.document + if (doc.languageId != "rust") return + // We need to order this after LS updates, but there's no API for that. + // Hence, good old setTimeout. + setTimeout(() => { + textDocumentContentProvider.eventEmitter.fire(uris.syntaxTree) + }, 10) + }, null, context.subscriptions) +} + +export function deactivate(): Thenable { + if (!client) { + return undefined; + } + return client.stop(); +} + +function startServer() { + let run: lc.Executable = { + command: "m", + // args: ["run", "--package", "m"], + options: { cwd: "." } + } + let serverOptions: lc.ServerOptions = { + run, + debug: run + }; + + let clientOptions: lc.LanguageClientOptions = { + documentSelector: [{ scheme: 'file', language: 'rust' }], + }; + + client = new lc.LanguageClient( + 'm', + 'm languge server', + serverOptions, + clientOptions, + ); + client.onReady().then(() => { + client.onNotification( + new lc.NotificationType("m/publishDecorations"), + (params: PublishDecorationsParams) => { + let editor = vscode.window.visibleTextEditors.find( + (editor) => editor.document.uri.toString() == params.uri + ) + if (editor == null) return; + setHighlights( + editor, + params.decorations, + ) + } + ) + }) + client.start(); +} + +async function openDoc(uri: vscode.Uri) { + let document = await vscode.workspace.openTextDocument(uri) + return vscode.window.showTextDocument(document, vscode.ViewColumn.Two, true) +} + +class TextDocumentContentProvider implements vscode.TextDocumentContentProvider { + public eventEmitter = new vscode.EventEmitter() + public syntaxTree: string = "Not available" + + public provideTextDocumentContent(uri: vscode.Uri): vscode.ProviderResult { + let editor = vscode.window.activeTextEditor; + if (editor == null) return "" + let request: SyntaxTreeParams = { + textDocument: { uri: editor.document.uri.toString() } + }; + return client.sendRequest("m/syntaxTree", request); + } + + get onDidChange(): vscode.Event { + return this.eventEmitter.event + } +} + + +const decorations = (() => { + const decor = (obj) => vscode.window.createTextEditorDecorationType({ color: obj }) + return { + background: decor("#3F3F3F"), + error: vscode.window.createTextEditorDecorationType({ + borderColor: "red", + borderStyle: "none none dashed none", + }), + comment: decor("#7F9F7F"), + string: decor("#CC9393"), + keyword: decor("#F0DFAF"), + function: decor("#93E0E3"), + parameter: decor("#94BFF3"), + builtin: decor("#DD6718"), + text: decor("#DCDCCC"), + attribute: decor("#BFEBBF"), + literal: decor("#DFAF8F"), + } +})() + +function setHighlights( + editor: vscode.TextEditor, + highlihgs: Array +) { + let byTag = {} + for (let tag in decorations) { + byTag[tag] = [] + } + + for (let d of highlihgs) { + if (!byTag[d.tag]) { + console.log(`unknown tag ${d.tag}`) + continue + } + byTag[d.tag].push(d.range) + } + + for (let tag in byTag) { + let dec = decorations[tag] + let ranges = byTag[tag] + editor.setDecorations(dec, ranges) + } +} + +interface SyntaxTreeParams { + textDocument: lc.TextDocumentIdentifier; +} + +type SyntaxTreeResult = string + +interface ExtendSelectionParams { + textDocument: lc.TextDocumentIdentifier; + selections: lc.Range[]; +} + +interface ExtendSelectionResult { + selections: lc.Range[]; +} + +interface PublishDecorationsParams { + uri: string, + decorations: Decoration[], +} + +interface Decoration { + range: lc.Range, + tag: string, +} diff --git a/code/src/main.ts b/code/src/main.ts deleted file mode 100644 index 72bef7061..000000000 --- a/code/src/main.ts +++ /dev/null @@ -1,208 +0,0 @@ -'use strict' -import * as vscode from 'vscode' - -const backend = require("../../native") - -let docToSyntax; - -let uris = { - syntaxTree: vscode.Uri.parse('libsyntax-rust://syntaxtree') -} - - -export function activate(context: vscode.ExtensionContext) { - let textDocumentContentProvider = new TextDocumentContentProvider() - let dispose = (disposable) => { - context.subscriptions.push(disposable); - } - - let registerCommand = (name, f) => { - dispose(vscode.commands.registerCommand(name, f)) - } - - docToSyntax = documentToFile(context.subscriptions, () => { - let emitter = textDocumentContentProvider.eventEmitter - emitter.fire(uris.syntaxTree) - let syntax = activeSyntax() - setHighlights(vscode.window.activeTextEditor, syntax.highlight()) - }) - - - dispose(vscode.workspace.registerTextDocumentContentProvider( - 'libsyntax-rust', - textDocumentContentProvider - )) - - registerCommand('libsyntax-rust.syntaxTree', () => openDoc(uris.syntaxTree)) - registerCommand('libsyntax-rust.extendSelection', () => { - let editor = vscode.window.activeTextEditor - let file = activeSyntax() - if (editor == null || file == null) return - editor.selections = editor.selections.map((s) => { - let range = file.extendSelection(s) - if (range == null) return null - return new vscode.Selection(range.start, range.end) - }) - }) -} - -export function deactivate() { } - -export class Syntax { - imp; - doc: vscode.TextDocument; - - constructor(imp, doc: vscode.TextDocument) { - this.imp = imp - this.doc = doc - } - - syntaxTree(): string { return this.imp.syntaxTree() } - highlight(): Array<[number, number, string]> { return this.imp.highlight() } - extendSelection(range: vscode.Range): vscode.Range { - let range_ = fromVsRange(this.doc, range); - let extRange = this.imp.extendSelection(range_[0], range_[1]); - return toVsRange(this.doc, extRange); - } -} - - -function activeDoc() { - return vscode.window.activeTextEditor.document -} - -function activeSyntax(): Syntax { - let doc = activeDoc() - if (doc == null) return null - return docToSyntax(doc) -} - -async function openDoc(uri: vscode.Uri) { - let document = await vscode.workspace.openTextDocument(uri) - return vscode.window.showTextDocument(document, vscode.ViewColumn.Two, true) -} - -function documentToFile(disposables: vscode.Disposable[], onChange) { - let docs = {} - function update(doc: vscode.TextDocument, file) { - let key = doc.uri.toString() - if (file == null) { - delete docs[key] - } else { - docs[key] = file - } - onChange(doc) - } - function get(doc: vscode.TextDocument) { - return docs[doc.uri.toString()] - } - - function isKnownDoc(doc: vscode.TextDocument) { - return doc.fileName.endsWith('.rs') - } - - function createFile(text: String) { - console.time("parsing") - let res = new backend.RustFile(text); - console.timeEnd("parsing") - return res - } - - vscode.workspace.onDidChangeTextDocument((event: vscode.TextDocumentChangeEvent) => { - let doc = event.document - if (!isKnownDoc(event.document)) return - update(doc, null) - }, null, disposables) - - vscode.workspace.onDidOpenTextDocument((doc: vscode.TextDocument) => { - if (!isKnownDoc(doc)) return - update(doc, createFile(doc.getText())) - }, null, disposables) - - vscode.workspace.onDidCloseTextDocument((doc: vscode.TextDocument) => { - update(doc, null) - }, null, disposables) - - return (doc: vscode.TextDocument) => { - if (!isKnownDoc(doc)) return null - - if (!get(doc)) { - update(doc, createFile(doc.getText())) - } - let imp = get(doc) - return new Syntax(imp, doc) - } -} - -export class TextDocumentContentProvider implements vscode.TextDocumentContentProvider { - public eventEmitter = new vscode.EventEmitter() - public syntaxTree: string = "Not available" - - public provideTextDocumentContent(uri: vscode.Uri): vscode.ProviderResult { - let syntax = activeSyntax() - if (syntax == null) return - if (uri.toString() == uris.syntaxTree.toString()) { - return syntax.syntaxTree() - } - } - - get onDidChange(): vscode.Event { - return this.eventEmitter.event - } -} - -const decorations = (() => { - const decor = (obj) => vscode.window.createTextEditorDecorationType({ color: obj }) - return { - background: decor("#3F3F3F"), - error: vscode.window.createTextEditorDecorationType({ - borderColor: "red", - borderStyle: "none none dashed none", - }), - comment: decor("#7F9F7F"), - string: decor("#CC9393"), - keyword: decor("#F0DFAF"), - function: decor("#93E0E3"), - parameter: decor("#94BFF3"), - builtin: decor("#DD6718"), - text: decor("#DCDCCC"), - attribute: decor("#BFEBBF"), - literal: decor("#DFAF8F"), - } -})() - -function setHighlights( - editor: vscode.TextEditor, - highlihgs: Array<[number, number, string]> -) { - let byTag = {} - for (let tag in decorations) { - byTag[tag] = [] - } - - for (let [start, end, tag] of highlihgs) { - if (!byTag[tag]) { - console.log(`unknown tag ${tag}`) - continue - } - let range = toVsRange(editor.document, [start, end]) - byTag[tag].push(range) - } - - for (let tag in byTag) { - let dec = decorations[tag] - let ranges = byTag[tag] - editor.setDecorations(dec, ranges) - } -} - -export function toVsRange(doc: vscode.TextDocument, range: [number, number]): vscode.Range { - return new vscode.Range( - doc.positionAt(range[0]), - doc.positionAt(range[1]), - ) -} - -function fromVsRange(doc: vscode.TextDocument, range: vscode.Range): [number, number] { - return [doc.offsetAt(range.start), doc.offsetAt(range.end)] -} -- cgit v1.2.3