1 import * as vscode from 'vscode';
2 import * as lc from 'vscode-languageclient';
4 import * as commands from './commands';
5 import { HintsUpdater } from './inlay_hints';
6 import { StatusDisplay } from './status_display';
7 import * as events from './events';
8 import * as notifications from './notifications';
9 import { Server } from './server';
10 import { Ctx } from './ctx';
14 export async function activate(context: vscode.ExtensionContext) {
15 ctx = new Ctx(context);
17 // Commands which invokes manually via command pallet, shortcut, etc.
18 ctx.registerCommand('analyzerStatus', commands.analyzerStatus);
19 ctx.registerCommand('collectGarbage', commands.collectGarbage);
20 ctx.registerCommand('matchingBrace', commands.matchingBrace);
21 ctx.registerCommand('joinLines', commands.joinLines);
22 ctx.registerCommand('parentModule', commands.parentModule);
23 ctx.registerCommand('syntaxTree', commands.syntaxTree);
24 ctx.registerCommand('expandMacro', commands.expandMacro);
25 ctx.registerCommand('run', commands.run);
27 // Internal commands which are invoked by the server.
28 ctx.registerCommand('runSingle', commands.runSingle);
29 ctx.registerCommand('showReferences', commands.showReferences);
31 if (Server.config.enableEnhancedTyping) {
32 ctx.overrideCommand('type', commands.onEnter);
35 const watchStatus = new StatusDisplay(
36 Server.config.cargoWatchOptions.command,
38 ctx.pushCleanup(watchStatus);
40 function disposeOnDeactivation(disposable: vscode.Disposable) {
41 context.subscriptions.push(disposable);
44 // Notifications are events triggered by the language server
45 const allNotifications: [string, lc.GenericNotificationHandler][] = [
47 'rust-analyzer/publishDecorations',
48 notifications.publishDecorations.handle,
52 params => watchStatus.handleProgressNotification(params),
56 // The events below are plain old javascript events, triggered and handled by vscode
57 vscode.window.onDidChangeActiveTextEditor(
58 events.changeActiveTextEditor.makeHandler(),
61 const startServer = () => Server.start(allNotifications);
62 const reloadCommand = () => reloadServer(startServer);
64 vscode.commands.registerCommand('rust-analyzer.reload', reloadCommand);
66 // Start the language server, finally!
70 vscode.window.showErrorMessage(e.message);
73 if (Server.config.displayInlayHints) {
74 const hintsUpdater = new HintsUpdater();
75 hintsUpdater.refreshHintsForVisibleEditors().then(() => {
76 // vscode may ignore top level hintsUpdater.refreshHintsForVisibleEditors()
77 // so update the hints once when the focus changes to guarantee their presence
78 let editorChangeDisposable: vscode.Disposable | null = null;
79 editorChangeDisposable = vscode.window.onDidChangeActiveTextEditor(
81 if (editorChangeDisposable !== null) {
82 editorChangeDisposable.dispose();
84 return hintsUpdater.refreshHintsForVisibleEditors();
88 disposeOnDeactivation(
89 vscode.window.onDidChangeVisibleTextEditors(_ =>
90 hintsUpdater.refreshHintsForVisibleEditors(),
93 disposeOnDeactivation(
94 vscode.workspace.onDidChangeTextDocument(e =>
95 hintsUpdater.refreshHintsForVisibleEditors(e),
98 disposeOnDeactivation(
99 vscode.workspace.onDidChangeConfiguration(_ =>
100 hintsUpdater.toggleHintsDisplay(
101 Server.config.displayInlayHints,
109 export function deactivate(): Thenable<void> {
110 if (!Server.client) {
111 return Promise.resolve();
113 return Server.client.stop();
116 async function reloadServer(startServer: () => Promise<void>) {
117 if (Server.client != null) {
118 vscode.window.showInformationMessage('Reloading rust-analyzer...');
119 await Server.client.stop();