From 33f9250d2139fa00038736515b9e22c51c419c01 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 12 Aug 2023 07:10:20 +0200 Subject: [PATCH 1/2] Pass server extraEnv to isValidExecutable --- editors/code/src/bootstrap.ts | 2 +- editors/code/src/util.ts | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/editors/code/src/bootstrap.ts b/editors/code/src/bootstrap.ts index ef4dff095cf..6cf399599d9 100644 --- a/editors/code/src/bootstrap.ts +++ b/editors/code/src/bootstrap.ts @@ -20,7 +20,7 @@ export async function bootstrap( log.info("Using server binary at", path); - if (!isValidExecutable(path)) { + if (!isValidExecutable(path, config.serverExtraEnv)) { if (config.serverPath) { throw new Error(`Failed to execute ${path} --version. \`config.server.path\` or \`config.serverPath\` has been set explicitly.\ Consider removing this config or making a valid server binary available at that path.`); diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts index 38ce6761578..e5394525772 100644 --- a/editors/code/src/util.ts +++ b/editors/code/src/util.ts @@ -2,6 +2,7 @@ import * as vscode from "vscode"; import { strict as nativeAssert } from "assert"; import { exec, type ExecOptions, spawnSync } from "child_process"; import { inspect } from "util"; +import { Env } from "./client"; export function assert(condition: boolean, explanation: string): asserts condition { try { @@ -93,10 +94,13 @@ export function isDocumentInWorkspace(document: RustDocument): boolean { return false; } -export function isValidExecutable(path: string): boolean { +export function isValidExecutable(path: string, extraEnv: Env): boolean { log.debug("Checking availability of a binary at", path); - const res = spawnSync(path, ["--version"], { encoding: "utf8" }); + const res = spawnSync(path, ["--version"], { + encoding: "utf8", + env: { ...process.env, ...extraEnv }, + }); const printOutput = res.error ? log.warn : log.info; printOutput(path, "--version:", res); From e76d20e072cd25ca2df21ef51e973bf666f4c840 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 12 Aug 2023 08:25:51 +0200 Subject: [PATCH 2/2] Add status bar button to toggle check on save state --- editors/code/package.json | 5 +++++ editors/code/src/commands.ts | 7 +++++++ editors/code/src/config.ts | 33 +++++++++++++++++++++++++++++++++ editors/code/src/ctx.ts | 18 ++++++++++++++++-- editors/code/src/main.ts | 1 + editors/code/src/util.ts | 2 +- 6 files changed, 63 insertions(+), 3 deletions(-) diff --git a/editors/code/package.json b/editors/code/package.json index 96fc8d7ecf0..83460c82c11 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -292,6 +292,11 @@ "command": "rust-analyzer.viewMemoryLayout", "title": "View Memory Layout", "category": "rust-analyzer" + }, + { + "command": "rust-analyzer.toggleCheckOnSave", + "title": "Toggle Check on Save", + "category": "rust-analyzer" } ], "keybindings": [ diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index e21f536f26a..aba37bac27d 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts @@ -1407,3 +1407,10 @@ locate() ctx.pushExtCleanup(document); }; } + +export function toggleCheckOnSave(ctx: Ctx): Cmd { + return async () => { + await ctx.config.toggleCheckOnSave(); + ctx.refreshServerStatus(); + }; +} diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 0e64054c11d..39e2f767c76 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -216,6 +216,39 @@ export class Config { ), ); } + get checkOnSave() { + return this.get("checkOnSave") ?? false; + } + async toggleCheckOnSave() { + const config = this.cfg.inspect("checkOnSave") ?? { key: "checkOnSave" }; + let overrideInLanguage; + let target; + let value; + if ( + config.workspaceFolderValue !== undefined || + config.workspaceFolderLanguageValue !== undefined + ) { + target = vscode.ConfigurationTarget.WorkspaceFolder; + overrideInLanguage = config.workspaceFolderLanguageValue; + value = config.workspaceFolderValue || config.workspaceFolderLanguageValue; + } else if ( + config.workspaceValue !== undefined || + config.workspaceLanguageValue !== undefined + ) { + target = vscode.ConfigurationTarget.Workspace; + overrideInLanguage = config.workspaceLanguageValue; + value = config.workspaceValue || config.workspaceLanguageValue; + } else if (config.globalValue !== undefined || config.globalLanguageValue !== undefined) { + target = vscode.ConfigurationTarget.Global; + overrideInLanguage = config.globalLanguageValue; + value = config.globalValue || config.globalLanguageValue; + } else if (config.defaultValue !== undefined || config.defaultLanguageValue !== undefined) { + overrideInLanguage = config.defaultLanguageValue; + value = config.defaultValue || config.defaultLanguageValue; + } + await this.cfg.update("checkOnSave", !(value || false), target || null, overrideInLanguage); + } + get traceExtension() { return this.get("trace.extension"); } diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index 16c14ca54f2..363a7a82e68 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -94,6 +94,7 @@ export class Ctx { private unlinkedFiles: vscode.Uri[]; private _dependencies: RustDependenciesProvider | undefined; private _treeView: vscode.TreeView | undefined; + private lastStatus: ServerStatusParams | { health: "stopped" } = { health: "stopped" }; get client() { return this._client; @@ -404,7 +405,15 @@ export class Ctx { } setServerStatus(status: ServerStatusParams | { health: "stopped" }) { + this.lastStatus = status; + this.updateStatusBarItem(); + } + refreshServerStatus() { + this.updateStatusBarItem(); + } + private updateStatusBarItem() { let icon = ""; + const status = this.lastStatus; const statusBar = this.statusBar; statusBar.show(); statusBar.tooltip = new vscode.MarkdownString("", true); @@ -447,13 +456,18 @@ export class Ctx { "statusBarItem.warningBackground", ); statusBar.command = "rust-analyzer.startServer"; - statusBar.text = `$(stop-circle) rust-analyzer`; + statusBar.text = "$(stop-circle) rust-analyzer"; return; } if (statusBar.tooltip.value) { statusBar.tooltip.appendMarkdown("\n\n---\n\n"); } - statusBar.tooltip.appendMarkdown("\n\n[Open logs](command:rust-analyzer.openLogs)"); + statusBar.tooltip.appendMarkdown("\n\n[Open Logs](command:rust-analyzer.openLogs)"); + statusBar.tooltip.appendMarkdown( + `\n\n[${ + this.config.checkOnSave ? "Disable" : "Enable" + } Check on Save](command:rust-analyzer.toggleCheckOnSave)`, + ); statusBar.tooltip.appendMarkdown( "\n\n[Reload Workspace](command:rust-analyzer.reloadWorkspace)", ); diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 448150bac06..ee5e5b1b80c 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -180,6 +180,7 @@ function createCommands(): Record { ssr: { enabled: commands.ssr }, serverVersion: { enabled: commands.serverVersion }, viewMemoryLayout: { enabled: commands.viewMemoryLayout }, + toggleCheckOnSave: { enabled: commands.toggleCheckOnSave }, // Internal commands which are invoked by the server. applyActionGroup: { enabled: commands.applyActionGroup }, applySnippetWorkspaceEdit: { enabled: commands.applySnippetWorkspaceEditCommand }, diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts index e5394525772..1e83c281a13 100644 --- a/editors/code/src/util.ts +++ b/editors/code/src/util.ts @@ -2,7 +2,7 @@ import * as vscode from "vscode"; import { strict as nativeAssert } from "assert"; import { exec, type ExecOptions, spawnSync } from "child_process"; import { inspect } from "util"; -import { Env } from "./client"; +import type { Env } from "./client"; export function assert(condition: boolean, explanation: string): asserts condition { try {