about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-07-22 10:49:32 +0200
committerLukas Wirth <lukastw97@gmail.com>2024-07-22 10:49:32 +0200
commit74cc2802b9a5b6e4f43ac9fa704703ed30b9c2d0 (patch)
tree72b3dfacdfbce3c679cd54f5e151d6a91fc4ccd9
parent5236347f7c30f3c611f37db395568dd37d12fa0e (diff)
downloadrust-74cc2802b9a5b6e4f43ac9fa704703ed30b9c2d0.tar.gz
rust-74cc2802b9a5b6e4f43ac9fa704703ed30b9c2d0.zip
Use rustup rust-analyzer component when there is a toolchain file override for the opened workspace
-rw-r--r--src/tools/rust-analyzer/editors/code/src/bootstrap.ts33
-rw-r--r--src/tools/rust-analyzer/editors/code/src/ctx.ts29
2 files changed, 44 insertions, 18 deletions
diff --git a/src/tools/rust-analyzer/editors/code/src/bootstrap.ts b/src/tools/rust-analyzer/editors/code/src/bootstrap.ts
index f2884ad0b05..527edf19eb4 100644
--- a/src/tools/rust-analyzer/editors/code/src/bootstrap.ts
+++ b/src/tools/rust-analyzer/editors/code/src/bootstrap.ts
@@ -42,6 +42,7 @@ async function getServer(
         enableProposedApi: boolean | undefined;
     } = context.extension.packageJSON;
 
+    // check if the server path is configured explicitly
     const explicitPath = process.env["__RA_LSP_SERVER_DEBUG"] ?? config.serverPath;
     if (explicitPath) {
         if (explicitPath.startsWith("~/")) {
@@ -51,12 +52,29 @@ async function getServer(
     }
     if (packageJson.releaseTag === null) return "rust-analyzer";
 
+    if (vscode.workspace.workspaceFolders?.length === 1) {
+        // otherwise check if there is a toolchain override for the current vscode workspace
+        // and if the toolchain of this override has a rust-analyzer component
+        // if so, use the rust-analyzer component
+        const toolchainTomlExists = await fileExists(
+            vscode.Uri.joinPath(vscode.workspace.workspaceFolders[0]!.uri, "rust-toolchain.toml"),
+        );
+        if (toolchainTomlExists) {
+            const res = spawnSync("rustup", ["which", "rust-analyzer"], {
+                encoding: "utf8",
+                env: { ...process.env },
+                cwd: vscode.workspace.workspaceFolders[0]!.uri.fsPath,
+            });
+            if (!res.error && res.status === 0) {
+                return res.stdout.trim();
+            }
+        }
+    }
+
+    // finally, use the bundled one
     const ext = process.platform === "win32" ? ".exe" : "";
     const bundled = vscode.Uri.joinPath(context.extensionUri, "server", `rust-analyzer${ext}`);
-    const bundledExists = await vscode.workspace.fs.stat(bundled).then(
-        () => true,
-        () => false,
-    );
+    const bundledExists = await fileExists(bundled);
     if (bundledExists) {
         let server = bundled;
         if (await isNixOs()) {
@@ -84,6 +102,13 @@ async function getServer(
     return undefined;
 }
 
+async function fileExists(uri: vscode.Uri) {
+    return await vscode.workspace.fs.stat(uri).then(
+        () => true,
+        () => false,
+    );
+}
+
 export function isValidExecutable(path: string, extraEnv: Env): boolean {
     log.debug("Checking availability of a binary at", path);
 
diff --git a/src/tools/rust-analyzer/editors/code/src/ctx.ts b/src/tools/rust-analyzer/editors/code/src/ctx.ts
index caa99d76194..675bfda65ab 100644
--- a/src/tools/rust-analyzer/editors/code/src/ctx.ts
+++ b/src/tools/rust-analyzer/editors/code/src/ctx.ts
@@ -187,19 +187,7 @@ export class Ctx implements RustAnalyzerExtensionApi {
         }
 
         if (!this._client) {
-            this._serverPath = await bootstrap(this.extCtx, this.config, this.state).catch(
-                (err) => {
-                    let message = "bootstrap error. ";
-
-                    message +=
-                        'See the logs in "OUTPUT > Rust Analyzer Client" (should open automatically). ';
-                    message +=
-                        'To enable verbose logs use { "rust-analyzer.trace.extension": true }';
-
-                    log.error("Bootstrap error", err);
-                    throw new Error(message);
-                },
-            );
+            this._serverPath = await this.bootstrap();
             text(spawn(this._serverPath, ["--version"]).stdout.setEncoding("utf-8")).then(
                 (data) => {
                     const prefix = `rust-analyzer `;
@@ -291,6 +279,19 @@ export class Ctx implements RustAnalyzerExtensionApi {
         return this._client;
     }
 
+    private async bootstrap(): Promise<string> {
+        return bootstrap(this.extCtx, this.config, this.state).catch((err) => {
+            let message = "bootstrap error. ";
+
+            message +=
+                'See the logs in "OUTPUT > Rust Analyzer Client" (should open automatically). ';
+            message += 'To enable verbose logs use { "rust-analyzer.trace.extension": true }';
+
+            log.error("Bootstrap error", err);
+            throw new Error(message);
+        });
+    }
+
     async start() {
         log.info("Starting language client");
         const client = await this.getOrCreateClient();
@@ -501,7 +502,7 @@ export class Ctx implements RustAnalyzerExtensionApi {
 
         const toggleCheckOnSave = this.config.checkOnSave ? "Disable" : "Enable";
         statusBar.tooltip.appendMarkdown(
-            `[Extension Info](command:analyzer.serverVersion "Show version and server binary info"): Version ${this.version}, Server Version ${this._serverVersion}` +
+            `[Extension Info](command:rust-analyzer.serverVersion "Show version and server binary info"): Version ${this.version}, Server Version ${this._serverVersion}` +
                 "\n\n---\n\n" +
                 '[$(terminal) Open Logs](command:rust-analyzer.openLogs "Open the server logs")' +
                 "\n\n" +