Skip to content

Commit 8ffdc2f

Browse files
Allow other extensions to override the configuration
1 parent 145677f commit 8ffdc2f

File tree

3 files changed

+31
-7
lines changed

3 files changed

+31
-7
lines changed

src/tools/rust-analyzer/editors/code/src/config.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as vscode from "vscode";
55
import { expectNotUndefined, log, normalizeDriveLetter, unwrapUndefinable } from "./util";
66
import type { Env } from "./util";
77
import type { Disposable } from "vscode";
8-
import { get } from "lodash";
8+
import { cloneDeep, get, merge } from "lodash";
99

1010
export type RunnableEnvCfgItem = {
1111
mask?: string;
@@ -23,14 +23,27 @@ export class Config {
2323
configureLang: vscode.Disposable | undefined;
2424

2525
readonly rootSection = "rust-analyzer";
26-
private readonly requiresServerReloadOpts = ["server", "files", "showSyntaxTree"].map(
26+
private readonly requiresServerReloadOpts = ["cargo", "server", "files", "showSyntaxTree"].map(
2727
(opt) => `${this.rootSection}.${opt}`,
2828
);
2929

3030
private readonly requiresWindowReloadOpts = ["testExplorer"].map(
3131
(opt) => `${this.rootSection}.${opt}`,
3232
);
3333

34+
extensionConfigurations: Map<string, Record<string, unknown>> = new Map();
35+
36+
async addExtensionConfiguration(extensionId: string, configuration: Record<string, unknown>): Promise<void> {
37+
this.extensionConfigurations.set(extensionId, configuration);
38+
const prefix = `${this.rootSection}.`;
39+
await this.onDidChangeConfiguration({
40+
affectsConfiguration(section: string, _scope?: vscode.ConfigurationScope): boolean {
41+
// FIXME: questionable
42+
return section.startsWith(prefix) && section.slice(prefix.length) in configuration;
43+
},
44+
});
45+
}
46+
3447
constructor(disposables: Disposable[]) {
3548
vscode.workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, disposables);
3649
this.refreshLogging();
@@ -180,10 +193,15 @@ export class Config {
180193
// We don't do runtime config validation here for simplicity. More on stackoverflow:
181194
// https://stackoverflow.com/questions/60135780/what-is-the-best-way-to-type-check-the-configuration-for-vscode-extension
182195

183-
private get cfg(): vscode.WorkspaceConfiguration {
196+
private get rawCfg(): vscode.WorkspaceConfiguration {
184197
return vscode.workspace.getConfiguration(this.rootSection);
185198
}
186199

200+
public get cfg(): ConfigurationTree {
201+
const vsCodeConfig = cloneDeep<ConfigurationTree>(this.rawCfg);
202+
return merge(vsCodeConfig, ...this.extensionConfigurations.values());
203+
}
204+
187205
/**
188206
* Beware that postfix `!` operator erases both `null` and `undefined`.
189207
* This is why the following doesn't work as expected:
@@ -227,7 +245,7 @@ export class Config {
227245
}
228246

229247
async toggleCheckOnSave() {
230-
const config = this.cfg.inspect<boolean>("checkOnSave") ?? { key: "checkOnSave" };
248+
const config = this.rawCfg.inspect<boolean>("checkOnSave") ?? { key: "checkOnSave" };
231249
let overrideInLanguage;
232250
let target;
233251
let value;
@@ -253,7 +271,7 @@ export class Config {
253271
overrideInLanguage = config.defaultLanguageValue;
254272
value = config.defaultValue || config.defaultLanguageValue;
255273
}
256-
await this.cfg.update("checkOnSave", !(value || false), target || null, overrideInLanguage);
274+
await this.rawCfg.update("checkOnSave", !(value || false), target || null, overrideInLanguage);
257275
}
258276

259277
get problemMatcher(): string[] {
@@ -371,7 +389,7 @@ export class Config {
371389
}
372390

373391
async setAskBeforeUpdateTest(value: boolean) {
374-
await this.cfg.update("runnables.askBeforeUpdateTest", value, true);
392+
await this.rawCfg.update("runnables.askBeforeUpdateTest", value, true);
375393
}
376394
}
377395

src/tools/rust-analyzer/editors/code/src/ctx.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ export class Ctx implements RustAnalyzerExtensionApi {
150150
});
151151
}
152152

153+
async addConfiguration(extensionId: string, configuration: Record<string, unknown>): Promise<void> {
154+
await this.config.addExtensionConfiguration(extensionId, configuration);
155+
}
156+
153157
dispose() {
154158
this.config.dispose();
155159
this.statusBar.dispose();
@@ -230,7 +234,7 @@ export class Ctx implements RustAnalyzerExtensionApi {
230234
debug: run,
231235
};
232236

233-
let rawInitializationOptions = vscode.workspace.getConfiguration("rust-analyzer");
237+
let rawInitializationOptions = this.config.cfg;
234238

235239
if (this.workspace.kind === "Detached Files") {
236240
rawInitializationOptions = {

src/tools/rust-analyzer/editors/code/src/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const RUST_PROJECT_CONTEXT_NAME = "inRustProject";
1313
export interface RustAnalyzerExtensionApi {
1414
// FIXME: this should be non-optional
1515
readonly client?: lc.LanguageClient;
16+
17+
addConfiguration(extensionId: string, configuration: Record<string, unknown>): Promise<void>;
1618
}
1719

1820
export async function deactivate() {

0 commit comments

Comments
 (0)