]> git.lizzy.rs Git - rust.git/blob - src/tools/rust-analyzer/editors/code/src/main.ts
:arrow_up: rust-analyzer
[rust.git] / src / tools / rust-analyzer / editors / code / src / main.ts
1 import * as vscode from "vscode";
2 import * as lc from "vscode-languageclient/node";
3
4 import * as commands from "./commands";
5 import { CommandFactory, Ctx, fetchWorkspace } from "./ctx";
6 import { activateTaskProvider } from "./tasks";
7 import { setContextValue } from "./util";
8
9 const RUST_PROJECT_CONTEXT_NAME = "inRustProject";
10
11 export interface RustAnalyzerExtensionApi {
12     readonly client?: lc.LanguageClient;
13 }
14
15 export async function deactivate() {
16     await setContextValue(RUST_PROJECT_CONTEXT_NAME, undefined);
17 }
18
19 export async function activate(
20     context: vscode.ExtensionContext
21 ): Promise<RustAnalyzerExtensionApi> {
22     if (vscode.extensions.getExtension("rust-lang.rust")) {
23         vscode.window
24             .showWarningMessage(
25                 `You have both the rust-analyzer (rust-lang.rust-analyzer) and Rust (rust-lang.rust) ` +
26                     "plugins enabled. These are known to conflict and cause various functions of " +
27                     "both plugins to not work correctly. You should disable one of them.",
28                 "Got it"
29             )
30             .then(() => {}, console.error);
31     }
32
33     const ctx = new Ctx(context, createCommands(), fetchWorkspace());
34     // VS Code doesn't show a notification when an extension fails to activate
35     // so we do it ourselves.
36     const api = await activateServer(ctx).catch((err) => {
37         void vscode.window.showErrorMessage(
38             `Cannot activate rust-analyzer extension: ${err.message}`
39         );
40         throw err;
41     });
42     await setContextValue(RUST_PROJECT_CONTEXT_NAME, true);
43     return api;
44 }
45
46 async function activateServer(ctx: Ctx): Promise<RustAnalyzerExtensionApi> {
47     if (ctx.workspace.kind === "Workspace Folder") {
48         ctx.pushExtCleanup(activateTaskProvider(ctx.config));
49     }
50
51     vscode.workspace.onDidChangeWorkspaceFolders(
52         async (_) => ctx.onWorkspaceFolderChanges(),
53         null,
54         ctx.subscriptions
55     );
56     vscode.workspace.onDidChangeConfiguration(
57         async (_) => {
58             await ctx.client?.sendNotification("workspace/didChangeConfiguration", {
59                 settings: "",
60             });
61         },
62         null,
63         ctx.subscriptions
64     );
65
66     await ctx.start();
67     return ctx;
68 }
69
70 function createCommands(): Record<string, CommandFactory> {
71     return {
72         onEnter: {
73             enabled: commands.onEnter,
74             disabled: (_) => () => vscode.commands.executeCommand("default:type", { text: "\n" }),
75         },
76         reload: {
77             enabled: (ctx) => async () => {
78                 void vscode.window.showInformationMessage("Reloading rust-analyzer...");
79                 await ctx.restart();
80             },
81             disabled: (ctx) => async () => {
82                 void vscode.window.showInformationMessage("Reloading rust-analyzer...");
83                 await ctx.start();
84             },
85         },
86         startServer: {
87             enabled: (ctx) => async () => {
88                 await ctx.start();
89             },
90             disabled: (ctx) => async () => {
91                 await ctx.start();
92             },
93         },
94         stopServer: {
95             enabled: (ctx) => async () => {
96                 // FIXME: We should re-use the client, that is ctx.deactivate() if none of the configs have changed
97                 await ctx.stopAndDispose();
98                 ctx.setServerStatus({
99                     health: "stopped",
100                 });
101             },
102             disabled: (_) => async () => {},
103         },
104
105         analyzerStatus: { enabled: commands.analyzerStatus },
106         memoryUsage: { enabled: commands.memoryUsage },
107         shuffleCrateGraph: { enabled: commands.shuffleCrateGraph },
108         reloadWorkspace: { enabled: commands.reloadWorkspace },
109         matchingBrace: { enabled: commands.matchingBrace },
110         joinLines: { enabled: commands.joinLines },
111         parentModule: { enabled: commands.parentModule },
112         syntaxTree: { enabled: commands.syntaxTree },
113         viewHir: { enabled: commands.viewHir },
114         viewFileText: { enabled: commands.viewFileText },
115         viewItemTree: { enabled: commands.viewItemTree },
116         viewCrateGraph: { enabled: commands.viewCrateGraph },
117         viewFullCrateGraph: { enabled: commands.viewFullCrateGraph },
118         expandMacro: { enabled: commands.expandMacro },
119         run: { enabled: commands.run },
120         copyRunCommandLine: { enabled: commands.copyRunCommandLine },
121         debug: { enabled: commands.debug },
122         newDebugConfig: { enabled: commands.newDebugConfig },
123         openDocs: { enabled: commands.openDocs },
124         openCargoToml: { enabled: commands.openCargoToml },
125         peekTests: { enabled: commands.peekTests },
126         moveItemUp: { enabled: commands.moveItemUp },
127         moveItemDown: { enabled: commands.moveItemDown },
128         cancelFlycheck: { enabled: commands.cancelFlycheck },
129         ssr: { enabled: commands.ssr },
130         serverVersion: { enabled: commands.serverVersion },
131         // Internal commands which are invoked by the server.
132         applyActionGroup: { enabled: commands.applyActionGroup },
133         applySnippetWorkspaceEdit: { enabled: commands.applySnippetWorkspaceEditCommand },
134         debugSingle: { enabled: commands.debugSingle },
135         gotoLocation: { enabled: commands.gotoLocation },
136         linkToCommand: { enabled: commands.linkToCommand },
137         resolveCodeAction: { enabled: commands.resolveCodeAction },
138         runSingle: { enabled: commands.runSingle },
139         showReferences: { enabled: commands.showReferences },
140     };
141 }