]> git.lizzy.rs Git - rust.git/blob - editors/code/src/config.ts
Merge #3694
[rust.git] / editors / code / src / config.ts
1 import * as vscode from 'vscode';
2 import { log } from "./util";
3
4 export type UpdatesChannel = "stable" | "nightly";
5
6 export const NIGHTLY_TAG = "nightly";
7
8 export class Config {
9     readonly extensionId = "matklad.rust-analyzer";
10
11     private readonly rootSection = "rust-analyzer";
12     private readonly requiresReloadOpts = [
13         "serverPath",
14         "cargoFeatures",
15         "cargo-watch",
16         "highlighting.semanticTokens",
17         "inlayHints",
18         "updates.channel",
19     ]
20         .map(opt => `${this.rootSection}.${opt}`);
21
22     readonly package: {
23         version: string;
24         releaseTag: string | undefined;
25         enableProposedApi: boolean | undefined;
26     } = vscode.extensions.getExtension(this.extensionId)!.packageJSON;
27
28     readonly globalStoragePath: string;
29
30     constructor(ctx: vscode.ExtensionContext) {
31         this.globalStoragePath = ctx.globalStoragePath;
32         vscode.workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, ctx.subscriptions);
33         this.refreshLogging();
34     }
35
36     private refreshLogging() {
37         log.setEnabled(this.traceExtension);
38         log.debug(
39             "Extension version:", this.package.version,
40             "using configuration:", this.cfg
41         );
42     }
43
44     private async onDidChangeConfiguration(event: vscode.ConfigurationChangeEvent) {
45         this.refreshLogging();
46
47         const requiresReloadOpt = this.requiresReloadOpts.find(
48             opt => event.affectsConfiguration(opt)
49         );
50
51         if (!requiresReloadOpt) return;
52
53         const userResponse = await vscode.window.showInformationMessage(
54             `Changing "${requiresReloadOpt}" requires a reload`,
55             "Reload now"
56         );
57
58         if (userResponse === "Reload now") {
59             await vscode.commands.executeCommand("workbench.action.reloadWindow");
60         }
61     }
62
63     // We don't do runtime config validation here for simplicity. More on stackoverflow:
64     // https://stackoverflow.com/questions/60135780/what-is-the-best-way-to-type-check-the-configuration-for-vscode-extension
65
66     private get cfg(): vscode.WorkspaceConfiguration {
67         return vscode.workspace.getConfiguration(this.rootSection);
68     }
69
70     get serverPath() { return this.cfg.get<null | string>("serverPath")!; }
71     get channel() { return this.cfg.get<UpdatesChannel>("updates.channel")!; }
72     get askBeforeDownload() { return this.cfg.get<boolean>("updates.askBeforeDownload")!; }
73     get highlightingSemanticTokens() { return this.cfg.get<boolean>("highlighting.semanticTokens")!; }
74     get highlightingOn() { return this.cfg.get<boolean>("highlightingOn")!; }
75     get rainbowHighlightingOn() { return this.cfg.get<boolean>("rainbowHighlightingOn")!; }
76     get lruCapacity() { return this.cfg.get<null | number>("lruCapacity")!; }
77     get excludeGlobs() { return this.cfg.get<string[]>("excludeGlobs")!; }
78     get useClientWatching() { return this.cfg.get<boolean>("useClientWatching")!; }
79     get featureFlags() { return this.cfg.get<Record<string, boolean>>("featureFlags")!; }
80     get rustfmtArgs() { return this.cfg.get<string[]>("rustfmtArgs")!; }
81     get loadOutDirsFromCheck() { return this.cfg.get<boolean>("loadOutDirsFromCheck")!; }
82     get traceExtension() { return this.cfg.get<boolean>("trace.extension")!; }
83
84     // for internal use
85     get withSysroot() { return this.cfg.get<boolean>("withSysroot", true)!; }
86
87     get inlayHints() {
88         return {
89             typeHints: this.cfg.get<boolean>("inlayHints.typeHints")!,
90             parameterHints: this.cfg.get<boolean>("inlayHints.parameterHints")!,
91             maxLength: this.cfg.get<null | number>("inlayHints.maxLength")!,
92         };
93     }
94
95     get cargoWatchOptions() {
96         return {
97             enable: this.cfg.get<boolean>("cargo-watch.enable")!,
98             arguments: this.cfg.get<string[]>("cargo-watch.arguments")!,
99             allTargets: this.cfg.get<boolean>("cargo-watch.allTargets")!,
100             command: this.cfg.get<string>("cargo-watch.command")!,
101         };
102     }
103
104     get cargoFeatures() {
105         return {
106             noDefaultFeatures: this.cfg.get<boolean>("cargoFeatures.noDefaultFeatures")!,
107             allFeatures: this.cfg.get<boolean>("cargoFeatures.allFeatures")!,
108             features: this.cfg.get<string[]>("cargoFeatures.features")!,
109             loadOutDirsFromCheck: this.cfg.get<boolean>("cargoFeatures.loadOutDirsFromCheck")!,
110         };
111     }
112 }