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",
18 * HOME_VAR is a placeholder for the home directory of the current user
19 * that the extension must replace when loading paths from settings.
21 export const HOME_VAR = "${HOME}";
23 export type Setting = string | boolean | string[] | null | undefined;
25 export interface PackageJSON {
30 export type GlobalStateType = Memento & {
31 setKeysForSync(keys: readonly string[]): void;
34 const LAST_PROJECT_ROOT_STATE_KEY = "lastProjectRoot";
36 export default class Settings {
37 private static instance?: Settings;
38 private config: WorkspaceConfiguration;
39 public workspaceState: Memento;
40 public globalState: GlobalStateType;
41 private pkg: PackageJSON;
44 workspaceState: Memento,
45 globalState: GlobalStateType,
46 packageJSON: PackageJSON
48 this.workspaceState = workspaceState;
49 this.globalState = globalState;
50 this.pkg = packageJSON;
52 this.config = workspace.getConfiguration(packageJSON.name);
55 public static createInstance(
56 workspaceState: Memento,
57 globalState: GlobalStateType,
58 packageJSON: PackageJSON
60 Settings.instance = new Settings(workspaceState, globalState, packageJSON);
62 return Settings.instance;
65 public static getInstance(): Settings | undefined {
66 // TODO: maybe remove to increase performance
67 Settings.instance?.reload();
69 return Settings.instance;
72 public reload(): void {
73 this.config = workspace.getConfiguration(this.pkg.name);
76 public get(key: SettingsKey): Setting {
77 return this.config.get(key);
80 public getIt<T>(key: SettingsKey): T | undefined {
81 const value = this.config.get(key);
82 // TODO: typeof value !== T does currently not work in TypeScript
83 // but if it could be a good backend for getString, getBoolean and so on
84 if (value === undefined) {
91 public getString(key: SettingsKey): string | undefined {
92 const value = this.get(key);
94 return typeof value === "string" ? value : undefined;
97 public getBoolean(key: SettingsKey): boolean | undefined {
98 const value = this.get(key);
100 return typeof value === "boolean" ? value : undefined;
103 public getArray(key: SettingsKey): string[] | undefined {
104 const value = this.get(key);
106 return Array.isArray(value) ? value : undefined;
109 public update<T>(key: SettingsKey, value: T): Thenable<void> {
110 // null == workspace folder settings, false == workspace settings
111 return this.config.update(key, value, null);
114 public updateGlobal<T>(key: SettingsKey, value: T): Thenable<void> {
115 return this.config.update(key, value, true);
119 public getExtensionName(): string {
120 return this.pkg.name;
123 public getExtensionId(): string {
124 return [this.pkg.publisher, this.pkg.name].join(".");
127 public async setLastProjectRoot(root: Uri): Promise<void> {
128 // saving fsPath not uri project as it would get corrupted and lose its
129 // fsPath property after loading
130 await this.globalState.update(LAST_PROJECT_ROOT_STATE_KEY, root.fsPath);
133 public getLastProjectRoot(): Uri {
134 const fsPath = this.globalState.get<string>(
135 LAST_PROJECT_ROOT_STATE_KEY,
136 // default to home directory as new project root
140 return Uri.file(fsPath);