diff --git a/editors/code/package.json b/editors/code/package.json index bdd8a0c298fa..87c3db22ac3b 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -476,6 +476,11 @@ "default": null, "description": "Path to rust-analyzer executable (points to bundled binary by default). If this is set, then \"rust-analyzer.updates.channel\" setting is not used" }, + "rust-analyzer.serverEnv": { + "type": "object", + "default": null, + "description": "Environment variables to set for the rust-analyzer executable in form of { \"key\": \"value\"}" + }, "rust-analyzer.trace.server": { "type": "string", "scope": "window", diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 1ba2352ee04e..c8c5013e00af 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -18,14 +18,14 @@ function renderHoverActions(actions: ra.CommandLinkGroup[]): vscode.MarkdownStri return result; } -export function createClient(serverPath: string, cwd: string): lc.LanguageClient { +export function createClient(serverPath: string, cwd: string, env: Record): lc.LanguageClient { // '.' Is the fallback if no folder is open // TODO?: Workspace folders support Uri's (eg: file://test.txt). // It might be a good idea to test if the uri points to a file. const run: lc.Executable = { command: serverPath, - options: { cwd }, + options: { cwd, env }, }; const serverOptions: lc.ServerOptions = { run, diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 848e92af9915..0f84e02f5663 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -5,6 +5,7 @@ export type UpdatesChannel = "stable" | "nightly"; export const NIGHTLY_TAG = "nightly"; +export type ServerEnvCfg = undefined | Record; export type RunnableEnvCfg = undefined | Record | { mask?: string; env: Record }[]; export class Config { @@ -13,6 +14,7 @@ export class Config { readonly rootSection = "rust-analyzer"; private readonly requiresReloadOpts = [ "serverPath", + "serverEnv", "cargo", "procMacro", "files", @@ -92,6 +94,7 @@ export class Config { } get serverPath() { return this.get("serverPath"); } + get serverEnv() { return this.get("serverEnv"); } get channel() { return this.get("updates.channel"); } get askBeforeDownload() { return this.get("updates.askBeforeDownload"); } get traceExtension() { return this.get("trace.extension"); } diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index d39864d330e1..e06a327bf37c 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -23,8 +23,9 @@ export class Ctx { extCtx: vscode.ExtensionContext, serverPath: string, cwd: string, + env: Record, ): Promise { - const client = createClient(serverPath, cwd); + const client = createClient(serverPath, cwd, env); const statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); extCtx.subscriptions.push(statusBar); diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 2896d90ac94b..9c4faa451db3 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -65,6 +65,7 @@ async function tryActivate(context: vscode.ExtensionContext) { log.error("Bootstrap error", err); throw new Error(message); }); + const env = config.serverEnv ?? {}; const workspaceFolder = vscode.workspace.workspaceFolders?.[0]; if (workspaceFolder === undefined) { @@ -75,7 +76,7 @@ async function tryActivate(context: vscode.ExtensionContext) { // registers its `onDidChangeDocument` handler before us. // // This a horribly, horribly wrong way to deal with this problem. - ctx = await Ctx.create(config, context, serverPath, workspaceFolder.uri.fsPath); + ctx = await Ctx.create(config, context, serverPath, workspaceFolder.uri.fsPath, env); setContextValue(RUST_PROJECT_CONTEXT_NAME, true);