1 import * as vscode from "vscode";
2 import * as lc from "vscode-languageclient/node";
4 import * as commands from "./commands";
5 import { CommandFactory, Ctx, fetchWorkspace } from "./ctx";
6 import { activateTaskProvider } from "./tasks";
7 import { setContextValue } from "./util";
9 const RUST_PROJECT_CONTEXT_NAME = "inRustProject";
11 export interface RustAnalyzerExtensionApi {
12 readonly client?: lc.LanguageClient;
15 export async function deactivate() {
16 await setContextValue(RUST_PROJECT_CONTEXT_NAME, undefined);
19 export async function activate(
20 context: vscode.ExtensionContext
21 ): Promise<RustAnalyzerExtensionApi> {
22 if (vscode.extensions.getExtension("rust-lang.rust")) {
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.",
30 .then(() => {}, console.error);
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}`
42 await setContextValue(RUST_PROJECT_CONTEXT_NAME, true);
46 async function activateServer(ctx: Ctx): Promise<RustAnalyzerExtensionApi> {
47 if (ctx.workspace.kind === "Workspace Folder") {
48 ctx.pushExtCleanup(activateTaskProvider(ctx.config));
51 vscode.workspace.onDidChangeWorkspaceFolders(
52 async (_) => ctx.onWorkspaceFolderChanges(),
56 vscode.workspace.onDidChangeConfiguration(
58 await ctx.client?.sendNotification("workspace/didChangeConfiguration", {
70 function createCommands(): Record<string, CommandFactory> {
73 enabled: commands.onEnter,
74 disabled: (_) => () => vscode.commands.executeCommand("default:type", { text: "\n" }),
77 enabled: (ctx) => async () => {
78 void vscode.window.showInformationMessage("Reloading rust-analyzer...");
81 disabled: (ctx) => async () => {
82 void vscode.window.showInformationMessage("Reloading rust-analyzer...");
87 enabled: (ctx) => async () => {
90 disabled: (ctx) => async () => {
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();
102 disabled: (_) => async () => {},
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 },