export class Config {
readonly extensionId = "matklad.rust-analyzer";
- private readonly rootSection = "rust-analyzer";
+ readonly rootSection = "rust-analyzer";
private readonly requiresReloadOpts = [
"serverPath",
- "cargoFeatures",
- "cargo-watch",
- "highlighting.semanticTokens",
- "inlayHints",
+ "cargo",
+ "procMacro",
+ "files",
+ "highlighting",
"updates.channel",
+ "lens.enable",
+ "lens.run",
+ "lens.debug",
+ "lens.implementations",
]
.map(opt => `${this.rootSection}.${opt}`);
- readonly packageJsonVersion: string = vscode
- .extensions
- .getExtension(this.extensionId)!
- .packageJSON
- .version;
-
- readonly releaseTag: string | undefined = vscode
- .extensions
- .getExtension(this.extensionId)!
- .packageJSON
- .releaseTag ?? undefined;
+ readonly package: {
+ version: string;
+ releaseTag: string | null;
+ enableProposedApi: boolean | undefined;
+ } = vscode.extensions.getExtension(this.extensionId)!.packageJSON;
readonly globalStoragePath: string;
private refreshLogging() {
log.setEnabled(this.traceExtension);
log.debug(
- "Extension version:", this.packageJsonVersion,
+ "Extension version:", this.package.version,
"using configuration:", this.cfg
);
}
return vscode.workspace.getConfiguration(this.rootSection);
}
- get serverPath() { return this.cfg.get<null | string>("serverPath")!; }
- get channel() { return this.cfg.get<UpdatesChannel>("updates.channel")!; }
- get askBeforeDownload() { return this.cfg.get<boolean>("updates.askBeforeDownload")!; }
- get highlightingSemanticTokens() { return this.cfg.get<boolean>("highlighting.semanticTokens")!; }
- get highlightingOn() { return this.cfg.get<boolean>("highlightingOn")!; }
- get rainbowHighlightingOn() { return this.cfg.get<boolean>("rainbowHighlightingOn")!; }
- get lruCapacity() { return this.cfg.get<null | number>("lruCapacity")!; }
- get excludeGlobs() { return this.cfg.get<string[]>("excludeGlobs")!; }
- get useClientWatching() { return this.cfg.get<boolean>("useClientWatching")!; }
- get featureFlags() { return this.cfg.get<Record<string, boolean>>("featureFlags")!; }
- get rustfmtArgs() { return this.cfg.get<string[]>("rustfmtArgs")!; }
- get loadOutDirsFromCheck() { return this.cfg.get<boolean>("loadOutDirsFromCheck")!; }
- get traceExtension() { return this.cfg.get<boolean>("trace.extension")!; }
-
- // for internal use
- get withSysroot() { return this.cfg.get<boolean>("withSysroot", true)!; }
+ /**
+ * Beware that postfix `!` operator erases both `null` and `undefined`.
+ * This is why the following doesn't work as expected:
+ *
+ * ```ts
+ * const nullableNum = vscode
+ * .workspace
+ * .getConfiguration
+ * .getConfiguration("rust-analyer")
+ * .get<number | null>(path)!;
+ *
+ * // What happens is that type of `nullableNum` is `number` but not `null | number`:
+ * const fullFledgedNum: number = nullableNum;
+ * ```
+ * So this getter handles this quirk by not requiring the caller to use postfix `!`
+ */
+ private get<T>(path: string): T {
+ return this.cfg.get<T>(path)!;
+ }
+
+ get serverPath() { return this.get<null | string>("serverPath"); }
+ get channel() { return this.get<UpdatesChannel>("updates.channel"); }
+ get askBeforeDownload() { return this.get<boolean>("updates.askBeforeDownload"); }
+ get traceExtension() { return this.get<boolean>("trace.extension"); }
get inlayHints() {
return {
- typeHints: this.cfg.get<boolean>("inlayHints.typeHints")!,
- parameterHints: this.cfg.get<boolean>("inlayHints.parameterHints")!,
- maxLength: this.cfg.get<null | number>("inlayHints.maxLength")!,
+ enable: this.get<boolean>("inlayHints.enable"),
+ typeHints: this.get<boolean>("inlayHints.typeHints"),
+ parameterHints: this.get<boolean>("inlayHints.parameterHints"),
+ chainingHints: this.get<boolean>("inlayHints.chainingHints"),
+ maxLength: this.get<null | number>("inlayHints.maxLength"),
+ };
+ }
+
+ get checkOnSave() {
+ return {
+ command: this.get<string>("checkOnSave.command"),
};
}
- get cargoWatchOptions() {
+ get debug() {
+ // "/rustc/<id>" used by suggestions only.
+ const { ["/rustc/<id>"]: _, ...sourceFileMap } = this.get<Record<string, string>>("debug.sourceFileMap");
+
return {
- enable: this.cfg.get<boolean>("cargo-watch.enable")!,
- arguments: this.cfg.get<string[]>("cargo-watch.arguments")!,
- allTargets: this.cfg.get<boolean>("cargo-watch.allTargets")!,
- command: this.cfg.get<string>("cargo-watch.command")!,
+ engine: this.get<string>("debug.engine"),
+ engineSettings: this.get<object>("debug.engineSettings"),
+ openUpDebugPane: this.get<boolean>("debug.openUpDebugPane"),
+ sourceFileMap: sourceFileMap
};
}
- get cargoFeatures() {
+ get lens() {
return {
- noDefaultFeatures: this.cfg.get<boolean>("cargoFeatures.noDefaultFeatures")!,
- allFeatures: this.cfg.get<boolean>("cargoFeatures.allFeatures")!,
- features: this.cfg.get<string[]>("cargoFeatures.features")!,
- loadOutDirsFromCheck: this.cfg.get<boolean>("cargoFeatures.loadOutDirsFromCheck")!,
+ enable: this.get<boolean>("lens.enable"),
+ run: this.get<boolean>("lens.run"),
+ debug: this.get<boolean>("lens.debug"),
+ implementations: this.get<boolean>("lens.implementations"),
};
}
}