From 86ee444fffd994ce220667e3d0b93e03e2e9cceb Mon Sep 17 00:00:00 2001 From: Michael Gruenewald Date: Tue, 7 Oct 2025 13:59:09 +0200 Subject: [PATCH 1/8] Add lodash --- editors/code/package-lock.json | 8 ++++++++ editors/code/package.json | 1 + 2 files changed, 9 insertions(+) diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json index e35a159cbc3f..6dd448522379 100644 --- a/editors/code/package-lock.json +++ b/editors/code/package-lock.json @@ -21,6 +21,7 @@ "@stylistic/eslint-plugin": "^4.1.0", "@stylistic/eslint-plugin-js": "^4.1.0", "@tsconfig/strictest": "^2.0.5", + "@types/lodash": "^4.17.20", "@types/node": "~22.13.4", "@types/vscode": "~1.93.0", "@typescript-eslint/eslint-plugin": "^8.25.0", @@ -1388,6 +1389,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "22.13.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz", diff --git a/editors/code/package.json b/editors/code/package.json index 70687238c854..d659421a0299 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -58,6 +58,7 @@ "@stylistic/eslint-plugin": "^4.1.0", "@stylistic/eslint-plugin-js": "^4.1.0", "@tsconfig/strictest": "^2.0.5", + "@types/lodash": "^4.17.20", "@types/node": "~22.13.4", "@types/vscode": "~1.93.0", "@typescript-eslint/eslint-plugin": "^8.25.0", From 410cf5575db1b074fe3c17970d4201c9f78c5bd1 Mon Sep 17 00:00:00 2001 From: Michael Gruenewald Date: Tue, 7 Oct 2025 13:55:49 +0200 Subject: [PATCH 2/8] Don't pretend to have a WorkspaceConfiguration if there isn't one --- editors/code/src/client.ts | 2 +- editors/code/src/config.ts | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 073ff2f4703f..cb71a01138b3 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -13,7 +13,7 @@ import { RaLanguageClient } from "./lang_client"; export async function createClient( traceOutputChannel: vscode.OutputChannel, outputChannel: vscode.OutputChannel, - initializationOptions: vscode.WorkspaceConfiguration, + initializationOptions: lc.LanguageClientOptions["initializationOptions"], serverOptions: lc.ServerOptions, config: Config, unlinkedFiles: vscode.Uri[], diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 3b1b0768d3cf..06e179eb0eb1 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -5,6 +5,7 @@ import * as vscode from "vscode"; import { expectNotUndefined, log, normalizeDriveLetter, unwrapUndefinable } from "./util"; import type { Env } from "./util"; import type { Disposable } from "vscode"; +import { get } from "lodash"; export type RunnableEnvCfgItem = { mask?: string; @@ -12,6 +13,9 @@ export type RunnableEnvCfgItem = { platform?: string | string[]; }; +export type ConfigurationTree = { [key: string]: ConfigurationValue }; +export type ConfigurationValue = undefined | null | boolean | number | string | ConfigurationValue[] | ConfigurationTree; + type ShowStatusBar = "always" | "never" | { documentSelector: vscode.DocumentSelector }; export class Config { @@ -197,7 +201,7 @@ export class Config { * So this getter handles this quirk by not requiring the caller to use postfix `!` */ private get(path: string): T | undefined { - return prepareVSCodeConfig(this.cfg.get(path)); + return prepareVSCodeConfig(get(this.cfg, path)) as T; } get serverPath() { @@ -371,22 +375,20 @@ export class Config { } } -export function prepareVSCodeConfig(resp: T): T { +export function prepareVSCodeConfig(resp: ConfigurationValue): ConfigurationValue { if (Is.string(resp)) { - return substituteVSCodeVariableInString(resp) as T; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } else if (resp && Is.array(resp)) { + return substituteVSCodeVariableInString(resp); + } else if (resp && Is.array(resp)) { return resp.map((val) => { return prepareVSCodeConfig(val); - }) as T; + }); } else if (resp && typeof resp === "object") { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const res: { [key: string]: any } = {}; + const res: ConfigurationTree = {}; for (const key in resp) { const val = resp[key]; res[key] = prepareVSCodeConfig(val); } - return res as T; + return res; } return resp; } From d1bfff1e3920b9b88f250e676a35337e9fcb529b Mon Sep 17 00:00:00 2001 From: Michael Gruenewald Date: Tue, 7 Oct 2025 14:06:30 +0200 Subject: [PATCH 3/8] Allow other extensions to override the configuration --- editors/code/src/config.ts | 30 ++++++++++++++++++++++++------ editors/code/src/ctx.ts | 6 +++++- editors/code/src/main.ts | 2 ++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 06e179eb0eb1..340f107ebbab 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -5,7 +5,7 @@ import * as vscode from "vscode"; import { expectNotUndefined, log, normalizeDriveLetter, unwrapUndefinable } from "./util"; import type { Env } from "./util"; import type { Disposable } from "vscode"; -import { get } from "lodash"; +import { cloneDeep, get, merge } from "lodash"; export type RunnableEnvCfgItem = { mask?: string; @@ -23,7 +23,7 @@ export class Config { configureLang: vscode.Disposable | undefined; readonly rootSection = "rust-analyzer"; - private readonly requiresServerReloadOpts = ["server", "files", "showSyntaxTree"].map( + private readonly requiresServerReloadOpts = ["cargo", "server", "files", "showSyntaxTree"].map( (opt) => `${this.rootSection}.${opt}`, ); @@ -31,6 +31,19 @@ export class Config { (opt) => `${this.rootSection}.${opt}`, ); + extensionConfigurations: Map> = new Map(); + + async addExtensionConfiguration(extensionId: string, configuration: Record): Promise { + this.extensionConfigurations.set(extensionId, configuration); + const prefix = `${this.rootSection}.`; + await this.onDidChangeConfiguration({ + affectsConfiguration(section: string, _scope?: vscode.ConfigurationScope): boolean { + // FIXME: questionable + return section.startsWith(prefix) && section.slice(prefix.length) in configuration; + }, + }); + } + constructor(disposables: Disposable[]) { vscode.workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, disposables); this.refreshLogging(); @@ -180,10 +193,15 @@ export class Config { // We don't do runtime config validation here for simplicity. More on stackoverflow: // https://stackoverflow.com/questions/60135780/what-is-the-best-way-to-type-check-the-configuration-for-vscode-extension - private get cfg(): vscode.WorkspaceConfiguration { + private get rawCfg(): vscode.WorkspaceConfiguration { return vscode.workspace.getConfiguration(this.rootSection); } + public get cfg(): ConfigurationTree { + const vsCodeConfig = cloneDeep(this.rawCfg); + return merge(vsCodeConfig, ...this.extensionConfigurations.values()); + } + /** * Beware that postfix `!` operator erases both `null` and `undefined`. * This is why the following doesn't work as expected: @@ -227,7 +245,7 @@ export class Config { } async toggleCheckOnSave() { - const config = this.cfg.inspect("checkOnSave") ?? { key: "checkOnSave" }; + const config = this.rawCfg.inspect("checkOnSave") ?? { key: "checkOnSave" }; let overrideInLanguage; let target; let value; @@ -253,7 +271,7 @@ export class Config { overrideInLanguage = config.defaultLanguageValue; value = config.defaultValue || config.defaultLanguageValue; } - await this.cfg.update("checkOnSave", !(value || false), target || null, overrideInLanguage); + await this.rawCfg.update("checkOnSave", !(value || false), target || null, overrideInLanguage); } get problemMatcher(): string[] { @@ -371,7 +389,7 @@ export class Config { } async setAskBeforeUpdateTest(value: boolean) { - await this.cfg.update("runnables.askBeforeUpdateTest", value, true); + await this.rawCfg.update("runnables.askBeforeUpdateTest", value, true); } } diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index e55754fb9f04..dfbf5b1e47c3 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -150,6 +150,10 @@ export class Ctx implements RustAnalyzerExtensionApi { }); } + async addConfiguration(extensionId: string, configuration: Record): Promise { + await this.config.addExtensionConfiguration(extensionId, configuration); + } + dispose() { this.config.dispose(); this.statusBar.dispose(); @@ -230,7 +234,7 @@ export class Ctx implements RustAnalyzerExtensionApi { debug: run, }; - let rawInitializationOptions = vscode.workspace.getConfiguration("rust-analyzer"); + let rawInitializationOptions = this.config.cfg; if (this.workspace.kind === "Detached Files") { rawInitializationOptions = { diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 996298524f11..c126a0a105dc 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -13,6 +13,8 @@ const RUST_PROJECT_CONTEXT_NAME = "inRustProject"; export interface RustAnalyzerExtensionApi { // FIXME: this should be non-optional readonly client?: lc.LanguageClient; + + addConfiguration(extensionId: string, configuration: Record): Promise; } export async function deactivate() { From c10226a8a135437f1a3c9e6418836cae55eb8225 Mon Sep 17 00:00:00 2001 From: Michael Gruenewald Date: Thu, 9 Oct 2025 14:21:16 +0200 Subject: [PATCH 4/8] Remember configuration overrides by extensions --- editors/code/src/config.ts | 50 +++++++++++++++++++++++--------------- editors/code/src/ctx.ts | 2 +- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 340f107ebbab..3afda6008263 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -4,8 +4,7 @@ import * as path from "path"; import * as vscode from "vscode"; import { expectNotUndefined, log, normalizeDriveLetter, unwrapUndefinable } from "./util"; import type { Env } from "./util"; -import type { Disposable } from "vscode"; -import { cloneDeep, get, merge } from "lodash"; +import { cloneDeep, get, merge, pickBy } from "lodash"; export type RunnableEnvCfgItem = { mask?: string; @@ -20,6 +19,7 @@ type ShowStatusBar = "always" | "never" | { documentSelector: vscode.DocumentSel export class Config { readonly extensionId = "rust-lang.rust-analyzer"; + readonly workspaceState: vscode.Memento; configureLang: vscode.Disposable | undefined; readonly rootSection = "rust-analyzer"; @@ -31,29 +31,43 @@ export class Config { (opt) => `${this.rootSection}.${opt}`, ); - extensionConfigurations: Map> = new Map(); + constructor(ctx: vscode.ExtensionContext) { + this.workspaceState = ctx.workspaceState; + vscode.workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, ctx.subscriptions); + this.refreshLogging(); + this.configureLanguage(); + } + + dispose() { + this.configureLang?.dispose(); + } + + /// Returns the rust-analyzer-specific workspace configuration, incl. any + /// configuration items overridden by (present) extensions. + get extensionConfigurations(): Record> { + return pickBy( + this.workspaceState.get>("extensionConfigurations", {}), + (_, extensionId) => vscode.extensions.getExtension(extensionId) !== undefined, + ); + } async addExtensionConfiguration(extensionId: string, configuration: Record): Promise { - this.extensionConfigurations.set(extensionId, configuration); + const oldConfiguration = this.cfg; + + const extCfgs = this.extensionConfigurations; + extCfgs[extensionId] = configuration; + await this.workspaceState.update("extensionConfigurations", extCfgs); + + const newConfiguration = this.cfg; const prefix = `${this.rootSection}.`; await this.onDidChangeConfiguration({ affectsConfiguration(section: string, _scope?: vscode.ConfigurationScope): boolean { - // FIXME: questionable - return section.startsWith(prefix) && section.slice(prefix.length) in configuration; + return section.startsWith(prefix) && + get(oldConfiguration, section.slice(prefix.length)) !== get(newConfiguration, section.slice(prefix.length)); }, }); } - constructor(disposables: Disposable[]) { - vscode.workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, disposables); - this.refreshLogging(); - this.configureLanguage(); - } - - dispose() { - this.configureLang?.dispose(); - } - private refreshLogging() { log.info( "Extension version:", @@ -198,8 +212,7 @@ export class Config { } public get cfg(): ConfigurationTree { - const vsCodeConfig = cloneDeep(this.rawCfg); - return merge(vsCodeConfig, ...this.extensionConfigurations.values()); + return merge(cloneDeep(this.rawCfg), ...Object.values(this.extensionConfigurations)); } /** @@ -209,7 +222,6 @@ export class Config { * ```ts * const nullableNum = vscode * .workspace - * .getConfiguration * .getConfiguration("rust-analyzer") * .get(path)!; * diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index dfbf5b1e47c3..69703efc6964 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -125,7 +125,7 @@ export class Ctx implements RustAnalyzerExtensionApi { extCtx.subscriptions.push(this); this.version = extCtx.extension.packageJSON.version ?? ""; this._serverVersion = ""; - this.config = new Config(extCtx.subscriptions); + this.config = new Config(extCtx); this.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); this.updateStatusBarVisibility(vscode.window.activeTextEditor); this.statusBarActiveEditorListener = vscode.window.onDidChangeActiveTextEditor((editor) => From 8355233a1974482406a00d981e21492d8b62d387 Mon Sep 17 00:00:00 2001 From: Michael Gruenewald Date: Mon, 13 Oct 2025 11:24:06 +0200 Subject: [PATCH 5/8] docs --- editors/code/src/config.ts | 14 +++++++++++--- editors/code/src/main.ts | 4 ++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 3afda6008263..4c895fb3d09b 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -19,10 +19,11 @@ type ShowStatusBar = "always" | "never" | { documentSelector: vscode.DocumentSel export class Config { readonly extensionId = "rust-lang.rust-analyzer"; - readonly workspaceState: vscode.Memento; + configureLang: vscode.Disposable | undefined; + workspaceState: vscode.Memento; - readonly rootSection = "rust-analyzer"; + private readonly rootSection = "rust-analyzer"; private readonly requiresServerReloadOpts = ["cargo", "server", "files", "showSyntaxTree"].map( (opt) => `${this.rootSection}.${opt}`, ); @@ -42,11 +43,14 @@ export class Config { this.configureLang?.dispose(); } + private readonly extensionConfigurationStateKey = "extensionConfigurations"; + /// Returns the rust-analyzer-specific workspace configuration, incl. any /// configuration items overridden by (present) extensions. get extensionConfigurations(): Record> { return pickBy( this.workspaceState.get>("extensionConfigurations", {}), + // ignore configurations from disabled/removed extensions (_, extensionId) => vscode.extensions.getExtension(extensionId) !== undefined, ); } @@ -56,7 +60,7 @@ export class Config { const extCfgs = this.extensionConfigurations; extCfgs[extensionId] = configuration; - await this.workspaceState.update("extensionConfigurations", extCfgs); + await this.workspaceState.update(this.extensionConfigurationStateKey, extCfgs); const newConfiguration = this.cfg; const prefix = `${this.rootSection}.`; @@ -207,10 +211,14 @@ export class Config { // We don't do runtime config validation here for simplicity. More on stackoverflow: // https://stackoverflow.com/questions/60135780/what-is-the-best-way-to-type-check-the-configuration-for-vscode-extension + // Returns the raw configuration for rust-analyzer as returned by vscode. This + // should only be used when modifications to the user/workspace configuration + // are required. private get rawCfg(): vscode.WorkspaceConfiguration { return vscode.workspace.getConfiguration(this.rootSection); } + // Returns the final configuration to use, with extension configuration overrides merged in. public get cfg(): ConfigurationTree { return merge(cloneDeep(this.rawCfg), ...Object.values(this.extensionConfigurations)); } diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index c126a0a105dc..1b512696ac57 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -14,6 +14,10 @@ export interface RustAnalyzerExtensionApi { // FIXME: this should be non-optional readonly client?: lc.LanguageClient; + // Allows adding a configuration override from another extension. + // `configuration` is a `rust-analyzer` subtree of the vscode configuration + // that gets merged with the workspace/user configuration. `extensionId` is + // used to only merge configuration override from present extensions. addConfiguration(extensionId: string, configuration: Record): Promise; } From ec452118231c48694ec2bfd3db74c12da688a2fe Mon Sep 17 00:00:00 2001 From: Michael Gruenewald Date: Mon, 13 Oct 2025 14:29:31 +0200 Subject: [PATCH 6/8] Don't override users' settings --- editors/code/src/config.ts | 16 ++++++++++++++-- editors/code/src/main.ts | 6 +++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 4c895fb3d09b..b97a47d5b984 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -4,7 +4,7 @@ import * as path from "path"; import * as vscode from "vscode"; import { expectNotUndefined, log, normalizeDriveLetter, unwrapUndefinable } from "./util"; import type { Env } from "./util"; -import { cloneDeep, get, merge, pickBy } from "lodash"; +import { cloneDeep, get, pickBy, set } from "lodash"; export type RunnableEnvCfgItem = { mask?: string; @@ -220,7 +220,19 @@ export class Config { // Returns the final configuration to use, with extension configuration overrides merged in. public get cfg(): ConfigurationTree { - return merge(cloneDeep(this.rawCfg), ...Object.values(this.extensionConfigurations)); + const finalConfig = cloneDeep(this.rawCfg); + for (const [extensionId, items] of Object.entries(this.extensionConfigurations)) { + for (const [k, v] of Object.entries(items)) { + const i = this.rawCfg.inspect(k); + if (i?.workspaceValue !== undefined || i?.workspaceFolderValue !== undefined || i?.globalValue !== undefined) { + log.trace(`Ignoring configuration override for ${k} from extension ${extensionId}`); + continue; + } + log.trace(`Extension ${extensionId} overrides configuration ${k} to `, v); + set(finalConfig, k, v); + } + } + return finalConfig; } /** diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 1b512696ac57..190f5866d0ea 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -15,9 +15,9 @@ export interface RustAnalyzerExtensionApi { readonly client?: lc.LanguageClient; // Allows adding a configuration override from another extension. - // `configuration` is a `rust-analyzer` subtree of the vscode configuration - // that gets merged with the workspace/user configuration. `extensionId` is - // used to only merge configuration override from present extensions. + // `extensionId` is used to only merge configuration override from present + // extensions. `configuration` is map of rust-analyzer-specific setting + // overrides, e.g., `{"cargo.cfgs": ["foo", "bar"]}`. addConfiguration(extensionId: string, configuration: Record): Promise; } From c5893b7c5ef15676396a42222a91d2064776b779 Mon Sep 17 00:00:00 2001 From: Michael Gruenewald Date: Mon, 13 Oct 2025 14:45:01 +0200 Subject: [PATCH 7/8] Format fixes --- editors/code/src/config.ts | 49 +++++++++++++++++++++++++++++++------- editors/code/src/ctx.ts | 5 +++- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index b97a47d5b984..c0a1b3f02e36 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -13,7 +13,14 @@ export type RunnableEnvCfgItem = { }; export type ConfigurationTree = { [key: string]: ConfigurationValue }; -export type ConfigurationValue = undefined | null | boolean | number | string | ConfigurationValue[] | ConfigurationTree; +export type ConfigurationValue = + | undefined + | null + | boolean + | number + | string + | ConfigurationValue[] + | ConfigurationTree; type ShowStatusBar = "always" | "never" | { documentSelector: vscode.DocumentSelector }; @@ -34,7 +41,11 @@ export class Config { constructor(ctx: vscode.ExtensionContext) { this.workspaceState = ctx.workspaceState; - vscode.workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, ctx.subscriptions); + vscode.workspace.onDidChangeConfiguration( + this.onDidChangeConfiguration, + this, + ctx.subscriptions, + ); this.refreshLogging(); this.configureLanguage(); } @@ -49,13 +60,19 @@ export class Config { /// configuration items overridden by (present) extensions. get extensionConfigurations(): Record> { return pickBy( - this.workspaceState.get>("extensionConfigurations", {}), + this.workspaceState.get>( + "extensionConfigurations", + {}, + ), // ignore configurations from disabled/removed extensions (_, extensionId) => vscode.extensions.getExtension(extensionId) !== undefined, ); } - async addExtensionConfiguration(extensionId: string, configuration: Record): Promise { + async addExtensionConfiguration( + extensionId: string, + configuration: Record, + ): Promise { const oldConfiguration = this.cfg; const extCfgs = this.extensionConfigurations; @@ -66,8 +83,11 @@ export class Config { const prefix = `${this.rootSection}.`; await this.onDidChangeConfiguration({ affectsConfiguration(section: string, _scope?: vscode.ConfigurationScope): boolean { - return section.startsWith(prefix) && - get(oldConfiguration, section.slice(prefix.length)) !== get(newConfiguration, section.slice(prefix.length)); + return ( + section.startsWith(prefix) && + get(oldConfiguration, section.slice(prefix.length)) !== + get(newConfiguration, section.slice(prefix.length)) + ); }, }); } @@ -224,8 +244,14 @@ export class Config { for (const [extensionId, items] of Object.entries(this.extensionConfigurations)) { for (const [k, v] of Object.entries(items)) { const i = this.rawCfg.inspect(k); - if (i?.workspaceValue !== undefined || i?.workspaceFolderValue !== undefined || i?.globalValue !== undefined) { - log.trace(`Ignoring configuration override for ${k} from extension ${extensionId}`); + if ( + i?.workspaceValue !== undefined || + i?.workspaceFolderValue !== undefined || + i?.globalValue !== undefined + ) { + log.trace( + `Ignoring configuration override for ${k} from extension ${extensionId}`, + ); continue; } log.trace(`Extension ${extensionId} overrides configuration ${k} to `, v); @@ -303,7 +329,12 @@ export class Config { overrideInLanguage = config.defaultLanguageValue; value = config.defaultValue || config.defaultLanguageValue; } - await this.rawCfg.update("checkOnSave", !(value || false), target || null, overrideInLanguage); + await this.rawCfg.update( + "checkOnSave", + !(value || false), + target || null, + overrideInLanguage, + ); } get problemMatcher(): string[] { diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index 69703efc6964..a7b7be03b5d8 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -150,7 +150,10 @@ export class Ctx implements RustAnalyzerExtensionApi { }); } - async addConfiguration(extensionId: string, configuration: Record): Promise { + async addConfiguration( + extensionId: string, + configuration: Record, + ): Promise { await this.config.addExtensionConfiguration(extensionId, configuration); } From 291aa7a60296fb363dc800dbc71733d3ca79c558 Mon Sep 17 00:00:00 2001 From: Michael Gruenewald Date: Sun, 26 Oct 2025 13:22:52 +0100 Subject: [PATCH 8/8] Don't add cargo to requiresServerReloadOpts --- editors/code/src/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index c0a1b3f02e36..5dc2c419efa8 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -31,7 +31,7 @@ export class Config { workspaceState: vscode.Memento; private readonly rootSection = "rust-analyzer"; - private readonly requiresServerReloadOpts = ["cargo", "server", "files", "showSyntaxTree"].map( + private readonly requiresServerReloadOpts = ["server", "files", "showSyntaxTree"].map( (opt) => `${this.rootSection}.${opt}`, );