From dc559dbe1c22b7200bcb6e3cd84dc105a0381c19 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 30 Dec 2019 12:19:58 +0100 Subject: Rename extension.ts -> main.ts --- editors/code/src/main.ts | 203 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 editors/code/src/main.ts (limited to 'editors/code/src/main.ts') diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts new file mode 100644 index 000000000..1da10ebd0 --- /dev/null +++ b/editors/code/src/main.ts @@ -0,0 +1,203 @@ +import * as vscode from 'vscode'; +import * as lc from 'vscode-languageclient'; + +import * as commands from './commands'; +import { ExpandMacroContentProvider } from './commands/expand_macro'; +import { HintsUpdater } from './commands/inlay_hints'; +import { SyntaxTreeContentProvider } from './commands/syntaxTree'; +import { StatusDisplay } from './commands/watch_status'; +import * as events from './events'; +import * as notifications from './notifications'; +import { Server } from './server'; + +export async function activate(context: vscode.ExtensionContext) { + function disposeOnDeactivation(disposable: vscode.Disposable) { + context.subscriptions.push(disposable); + } + + function registerCommand(name: string, f: any) { + disposeOnDeactivation(vscode.commands.registerCommand(name, f)); + } + function overrideCommand( + name: string, + f: (...args: any[]) => Promise, + ) { + const defaultCmd = `default:${name}`; + const original = (...args: any[]) => + vscode.commands.executeCommand(defaultCmd, ...args); + + try { + registerCommand(name, async (...args: any[]) => { + const editor = vscode.window.activeTextEditor; + if ( + !editor || + !editor.document || + editor.document.languageId !== 'rust' + ) { + return await original(...args); + } + if (!(await f(...args))) { + return await original(...args); + } + }); + } catch (_) { + vscode.window.showWarningMessage( + 'Enhanced typing feature is disabled because of incompatibility with VIM extension, consider turning off rust-analyzer.enableEnhancedTyping: https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/README.md#settings', + ); + } + } + + // Commands are requests from vscode to the language server + registerCommand( + 'rust-analyzer.analyzerStatus', + commands.analyzerStatus.makeCommand(context), + ); + registerCommand('rust-analyzer.collectGarbage', () => + Server.client.sendRequest('rust-analyzer/collectGarbage', null), + ); + registerCommand( + 'rust-analyzer.matchingBrace', + commands.matchingBrace.handle, + ); + registerCommand('rust-analyzer.joinLines', commands.joinLines.handle); + registerCommand('rust-analyzer.parentModule', commands.parentModule.handle); + registerCommand('rust-analyzer.run', commands.runnables.handle); + // Unlike the above this does not send requests to the language server + registerCommand('rust-analyzer.runSingle', commands.runnables.handleSingle); + registerCommand( + 'rust-analyzer.applySourceChange', + commands.applySourceChange.handle, + ); + registerCommand( + 'rust-analyzer.showReferences', + (uri: string, position: lc.Position, locations: lc.Location[]) => { + vscode.commands.executeCommand( + 'editor.action.showReferences', + vscode.Uri.parse(uri), + Server.client.protocol2CodeConverter.asPosition(position), + locations.map(Server.client.protocol2CodeConverter.asLocation), + ); + }, + ); + + if (Server.config.enableEnhancedTyping) { + overrideCommand('type', commands.onEnter.handle); + } + + const watchStatus = new StatusDisplay( + Server.config.cargoWatchOptions.command, + ); + disposeOnDeactivation(watchStatus); + + // Notifications are events triggered by the language server + const allNotifications: Iterable<[ + string, + lc.GenericNotificationHandler, + ]> = [ + [ + 'rust-analyzer/publishDecorations', + notifications.publishDecorations.handle, + ], + [ + '$/progress', + params => watchStatus.handleProgressNotification(params), + ], + ]; + const syntaxTreeContentProvider = new SyntaxTreeContentProvider(); + const expandMacroContentProvider = new ExpandMacroContentProvider(); + + // The events below are plain old javascript events, triggered and handled by vscode + vscode.window.onDidChangeActiveTextEditor( + events.changeActiveTextEditor.makeHandler(syntaxTreeContentProvider), + ); + + disposeOnDeactivation( + vscode.workspace.registerTextDocumentContentProvider( + 'rust-analyzer', + syntaxTreeContentProvider, + ), + ); + disposeOnDeactivation( + vscode.workspace.registerTextDocumentContentProvider( + 'rust-analyzer', + expandMacroContentProvider, + ), + ); + + registerCommand( + 'rust-analyzer.syntaxTree', + commands.syntaxTree.createHandle(syntaxTreeContentProvider), + ); + registerCommand( + 'rust-analyzer.expandMacro', + commands.expandMacro.createHandle(expandMacroContentProvider), + ); + + vscode.workspace.onDidChangeTextDocument( + events.changeTextDocument.createHandler(syntaxTreeContentProvider), + null, + context.subscriptions, + ); + + const startServer = () => Server.start(allNotifications); + const reloadCommand = () => reloadServer(startServer); + + vscode.commands.registerCommand('rust-analyzer.reload', reloadCommand); + + // Start the language server, finally! + try { + await startServer(); + } catch (e) { + vscode.window.showErrorMessage(e.message); + } + + if (Server.config.displayInlayHints) { + const hintsUpdater = new HintsUpdater(); + hintsUpdater.refreshHintsForVisibleEditors().then(() => { + // vscode may ignore top level hintsUpdater.refreshHintsForVisibleEditors() + // so update the hints once when the focus changes to guarantee their presence + let editorChangeDisposable: vscode.Disposable | null = null; + editorChangeDisposable = vscode.window.onDidChangeActiveTextEditor( + _ => { + if (editorChangeDisposable !== null) { + editorChangeDisposable.dispose(); + } + return hintsUpdater.refreshHintsForVisibleEditors(); + }, + ); + + disposeOnDeactivation( + vscode.window.onDidChangeVisibleTextEditors(_ => + hintsUpdater.refreshHintsForVisibleEditors(), + ), + ); + disposeOnDeactivation( + vscode.workspace.onDidChangeTextDocument(e => + hintsUpdater.refreshHintsForVisibleEditors(e), + ), + ); + disposeOnDeactivation( + vscode.workspace.onDidChangeConfiguration(_ => + hintsUpdater.toggleHintsDisplay( + Server.config.displayInlayHints, + ), + ), + ); + }); + } +} + +export function deactivate(): Thenable { + if (!Server.client) { + return Promise.resolve(); + } + return Server.client.stop(); +} + +async function reloadServer(startServer: () => Promise) { + if (Server.client != null) { + vscode.window.showInformationMessage('Reloading rust-analyzer...'); + await Server.client.stop(); + await startServer(); + } +} -- cgit v1.2.3