1 import { homedir } from "os";
2 import { type Memento, Uri, type WorkspaceConfiguration } from "vscode";
3 import { workspace } from "vscode";
6 * SettingsKey is a list of all settings keys added by this extension (with the extension prefix).
8 export enum SettingsKey {
9 cmakePath = "cmakePath",
10 python3Path = "python3Path",
11 ninjaPath = "ninjaPath",
13 cmakeAutoConfigure = "cmakeAutoConfigure",
14 githubToken = "githubToken",
15 useCmakeTools = "useCmakeTools",
19 * HOME_VAR is a placeholder for the home directory of the current user
20 * that the extension must replace when loading paths from settings.
22 export const HOME_VAR = "${HOME}";
24 export type Setting = string | boolean | string[] | null | undefined;
26 export interface PackageJSON {
31 export type GlobalStateType = Memento & {
32 setKeysForSync(keys: readonly string[]): void;
35 const LAST_PROJECT_ROOT_STATE_KEY = "lastProjectRoot";
37 export default class Settings {
38 private static instance?: Settings;
39 private config: WorkspaceConfiguration;
40 public workspaceState: Memento;
41 public globalState: GlobalStateType;
42 private pkg: PackageJSON;
45 workspaceState: Memento,
46 globalState: GlobalStateType,
47 packageJSON: PackageJSON
49 this.workspaceState = workspaceState;
50 this.globalState = globalState;
51 this.pkg = packageJSON;
53 this.config = workspace.getConfiguration(packageJSON.name);
56 public static createInstance(
57 workspaceState: Memento,
58 globalState: GlobalStateType,
59 packageJSON: PackageJSON
61 Settings.instance = new Settings(workspaceState, globalState, packageJSON);
63 return Settings.instance;
66 public static getInstance(): Settings | undefined {
67 // TODO: maybe remove to increase performance
68 Settings.instance?.reload();
70 return Settings.instance;
73 public reload(): void {
74 this.config = workspace.getConfiguration(this.pkg.name);
77 public get(key: SettingsKey): Setting {
78 return this.config.get(key);
81 public getIt<T>(key: SettingsKey): T | undefined {
82 const value = this.config.get(key);
83 // TODO: typeof value !== T does currently not work in TypeScript
84 // but if it could be a good backend for getString, getBoolean and so on
85 if (value === undefined) {
92 public getString(key: SettingsKey): string | undefined {
93 const value = this.get(key);
95 return typeof value === "string" ? value : undefined;
98 public getBoolean(key: SettingsKey): boolean | undefined {
99 const value = this.get(key);
101 return typeof value === "boolean" ? value : undefined;
104 public getArray(key: SettingsKey): string[] | undefined {
105 const value = this.get(key);
107 return Array.isArray(value) ? value : undefined;
110 public update<T>(key: SettingsKey, value: T): Thenable<void> {
111 // null == workspace folder settings, false == workspace settings
112 return this.config.update(key, value, null);
115 public updateGlobal<T>(key: SettingsKey, value: T): Thenable<void> {
116 return this.config.update(key, value, true);
120 public getExtensionName(): string {
121 return this.pkg.name;
124 public getExtensionId(): string {
125 return [this.pkg.publisher, this.pkg.name].join(".");
128 public async setLastProjectRoot(root: Uri): Promise<void> {
129 // saving fsPath not uri project as it would get corrupted and lose its
130 // fsPath property after loading
131 await this.globalState.update(LAST_PROJECT_ROOT_STATE_KEY, root.fsPath);
134 public getLastProjectRoot(): Uri {
135 const fsPath = this.globalState.get<string>(
136 LAST_PROJECT_ROOT_STATE_KEY,
137 // default to home directory as new project root
141 return Uri.file(fsPath);