@@ -4,8 +4,7 @@ import * as path from "path";
44import * as vscode from "vscode" ;
55import { expectNotUndefined , log , normalizeDriveLetter , unwrapUndefinable } from "./util" ;
66import type { Env } from "./util" ;
7- import type { Disposable } from "vscode" ;
8- import { cloneDeep , get , merge } from "lodash" ;
7+ import { cloneDeep , get , merge , pickBy } from "lodash" ;
98
109export type RunnableEnvCfgItem = {
1110 mask ?: string ;
@@ -20,6 +19,7 @@ type ShowStatusBar = "always" | "never" | { documentSelector: vscode.DocumentSel
2019
2120export class Config {
2221 readonly extensionId = "rust-lang.rust-analyzer" ;
22+ readonly workspaceState : vscode . Memento ;
2323 configureLang : vscode . Disposable | undefined ;
2424
2525 readonly rootSection = "rust-analyzer" ;
@@ -31,29 +31,43 @@ export class Config {
3131 ( opt ) => `${ this . rootSection } .${ opt } ` ,
3232 ) ;
3333
34- extensionConfigurations : Map < string , Record < string , unknown > > = new Map ( ) ;
34+ constructor ( ctx : vscode . ExtensionContext ) {
35+ this . workspaceState = ctx . workspaceState ;
36+ vscode . workspace . onDidChangeConfiguration ( this . onDidChangeConfiguration , this , ctx . subscriptions ) ;
37+ this . refreshLogging ( ) ;
38+ this . configureLanguage ( ) ;
39+ }
40+
41+ dispose ( ) {
42+ this . configureLang ?. dispose ( ) ;
43+ }
44+
45+ /// Returns the rust-analyzer-specific workspace configuration, incl. any
46+ /// configuration items overridden by (present) extensions.
47+ get extensionConfigurations ( ) : Record < string , Record < string , unknown > > {
48+ return pickBy (
49+ this . workspaceState . get < Record < string , ConfigurationTree > > ( "extensionConfigurations" , { } ) ,
50+ ( _ , extensionId ) => vscode . extensions . getExtension ( extensionId ) !== undefined ,
51+ ) ;
52+ }
3553
3654 async addExtensionConfiguration ( extensionId : string , configuration : Record < string , unknown > ) : Promise < void > {
37- this . extensionConfigurations . set ( extensionId , configuration ) ;
55+ const oldConfiguration = this . cfg ;
56+
57+ const extCfgs = this . extensionConfigurations ;
58+ extCfgs [ extensionId ] = configuration ;
59+ await this . workspaceState . update ( "extensionConfigurations" , extCfgs ) ;
60+
61+ const newConfiguration = this . cfg ;
3862 const prefix = `${ this . rootSection } .` ;
3963 await this . onDidChangeConfiguration ( {
4064 affectsConfiguration ( section : string , _scope ?: vscode . ConfigurationScope ) : boolean {
41- // FIXME: questionable
42- return section . startsWith ( prefix ) && section . slice ( prefix . length ) in configuration ;
65+ return section . startsWith ( prefix ) &&
66+ get ( oldConfiguration , section . slice ( prefix . length ) ) !== get ( newConfiguration , section . slice ( prefix . length ) ) ;
4367 } ,
4468 } ) ;
4569 }
4670
47- constructor ( disposables : Disposable [ ] ) {
48- vscode . workspace . onDidChangeConfiguration ( this . onDidChangeConfiguration , this , disposables ) ;
49- this . refreshLogging ( ) ;
50- this . configureLanguage ( ) ;
51- }
52-
53- dispose ( ) {
54- this . configureLang ?. dispose ( ) ;
55- }
56-
5771 private refreshLogging ( ) {
5872 log . info (
5973 "Extension version:" ,
@@ -198,8 +212,7 @@ export class Config {
198212 }
199213
200214 public get cfg ( ) : ConfigurationTree {
201- const vsCodeConfig = cloneDeep < ConfigurationTree > ( this . rawCfg ) ;
202- return merge ( vsCodeConfig , ...this . extensionConfigurations . values ( ) ) ;
215+ return merge ( cloneDeep ( this . rawCfg ) , ...Object . values ( this . extensionConfigurations ) ) ;
203216 }
204217
205218 /**
@@ -209,7 +222,6 @@ export class Config {
209222 * ```ts
210223 * const nullableNum = vscode
211224 * .workspace
212- * .getConfiguration
213225 * .getConfiguration("rust-analyzer")
214226 * .get<number | null>(path)!;
215227 *
0 commit comments