]> git.lizzy.rs Git - rust.git/blob - editors/code/src/main.ts
Move all commands to ctx
[rust.git] / editors / code / src / main.ts
1 import * as vscode from 'vscode';
2 import * as lc from 'vscode-languageclient';
3
4 import * as commands from './commands';
5 import { HintsUpdater } from './commands/inlay_hints';
6 import { StatusDisplay } from './commands/watch_status';
7 import * as events from './events';
8 import * as notifications from './notifications';
9 import { Server } from './server';
10 import { Ctx } from './ctx';
11
12 let ctx!: Ctx;
13
14 export async function activate(context: vscode.ExtensionContext) {
15     ctx = new Ctx(context);
16
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);
26
27     // Internal commands which are invoked by the server.
28     ctx.registerCommand('runSingle', commands.runSingle);
29     ctx.registerCommand('showReferences', commands.showReferences);
30
31     function disposeOnDeactivation(disposable: vscode.Disposable) {
32         context.subscriptions.push(disposable);
33     }
34
35     if (Server.config.enableEnhancedTyping) {
36         ctx.overrideCommand('type', commands.onEnter);
37     }
38
39     const watchStatus = new StatusDisplay(
40         Server.config.cargoWatchOptions.command,
41     );
42     disposeOnDeactivation(watchStatus);
43
44     // Notifications are events triggered by the language server
45     const allNotifications: [string, lc.GenericNotificationHandler][] = [
46         [
47             'rust-analyzer/publishDecorations',
48             notifications.publishDecorations.handle,
49         ],
50         [
51             '$/progress',
52             params => watchStatus.handleProgressNotification(params),
53         ],
54     ];
55
56     // The events below are plain old javascript events, triggered and handled by vscode
57     vscode.window.onDidChangeActiveTextEditor(
58         events.changeActiveTextEditor.makeHandler(),
59     );
60
61     const startServer = () => Server.start(allNotifications);
62     const reloadCommand = () => reloadServer(startServer);
63
64     vscode.commands.registerCommand('rust-analyzer.reload', reloadCommand);
65
66     // Start the language server, finally!
67     try {
68         await startServer();
69     } catch (e) {
70         vscode.window.showErrorMessage(e.message);
71     }
72
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(
80                 _ => {
81                     if (editorChangeDisposable !== null) {
82                         editorChangeDisposable.dispose();
83                     }
84                     return hintsUpdater.refreshHintsForVisibleEditors();
85                 },
86             );
87
88             disposeOnDeactivation(
89                 vscode.window.onDidChangeVisibleTextEditors(_ =>
90                     hintsUpdater.refreshHintsForVisibleEditors(),
91                 ),
92             );
93             disposeOnDeactivation(
94                 vscode.workspace.onDidChangeTextDocument(e =>
95                     hintsUpdater.refreshHintsForVisibleEditors(e),
96                 ),
97             );
98             disposeOnDeactivation(
99                 vscode.workspace.onDidChangeConfiguration(_ =>
100                     hintsUpdater.toggleHintsDisplay(
101                         Server.config.displayInlayHints,
102                     ),
103                 ),
104             );
105         });
106     }
107 }
108
109 export function deactivate(): Thenable<void> {
110     if (!Server.client) {
111         return Promise.resolve();
112     }
113     return Server.client.stop();
114 }
115
116 async function reloadServer(startServer: () => Promise<void>) {
117     if (Server.client != null) {
118         vscode.window.showInformationMessage('Reloading rust-analyzer...');
119         await Server.client.stop();
120         await startServer();
121     }
122 }