]> Git Repo - pico-vscode.git/blob - src/settings.mts
Some code refactoring
[pico-vscode.git] / src / settings.mts
1 import { homedir } from "os";
2 import { type Memento, Uri, type WorkspaceConfiguration } from "vscode";
3 import { workspace } from "vscode";
4
5 /**
6  * SettingsKey is a list of all settings keys added by this extension (with the extension prefix).
7  */
8 export enum SettingsKey {
9   cmakePath = "cmakePath",
10   python3Path = "python3Path",
11   ninjaPath = "ninjaPath",
12   gitPath = "gitPath",
13   cmakeAutoConfigure = "cmakeAutoConfigure",
14   githubToken = "githubToken",
15 }
16
17 /**
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.
20  */
21 export const HOME_VAR = "${HOME}";
22
23 export type Setting = string | boolean | string[] | null | undefined;
24
25 export interface PackageJSON {
26   name: string;
27   publisher: string;
28 }
29
30 export type GlobalStateType = Memento & {
31   setKeysForSync(keys: readonly string[]): void;
32 };
33
34 const LAST_PROJECT_ROOT_STATE_KEY = "lastProjectRoot";
35
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;
42
43   private constructor(
44     workspaceState: Memento,
45     globalState: GlobalStateType,
46     packageJSON: PackageJSON
47   ) {
48     this.workspaceState = workspaceState;
49     this.globalState = globalState;
50     this.pkg = packageJSON;
51
52     this.config = workspace.getConfiguration(packageJSON.name);
53   }
54
55   public static createInstance(
56     workspaceState: Memento,
57     globalState: GlobalStateType,
58     packageJSON: PackageJSON
59   ): Settings {
60     Settings.instance = new Settings(workspaceState, globalState, packageJSON);
61
62     return Settings.instance;
63   }
64
65   public static getInstance(): Settings | undefined {
66     // TODO: maybe remove to increase performance
67     Settings.instance?.reload();
68
69     return Settings.instance;
70   }
71
72   public reload(): void {
73     this.config = workspace.getConfiguration(this.pkg.name);
74   }
75
76   public get(key: SettingsKey): Setting {
77     return this.config.get(key);
78   }
79
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) {
85       return undefined;
86     }
87
88     return value as T;
89   }
90
91   public getString(key: SettingsKey): string | undefined {
92     const value = this.get(key);
93
94     return typeof value === "string" ? value : undefined;
95   }
96
97   public getBoolean(key: SettingsKey): boolean | undefined {
98     const value = this.get(key);
99
100     return typeof value === "boolean" ? value : undefined;
101   }
102
103   public getArray(key: SettingsKey): string[] | undefined {
104     const value = this.get(key);
105
106     return Array.isArray(value) ? value : undefined;
107   }
108
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);
112   }
113
114   public updateGlobal<T>(key: SettingsKey, value: T): Thenable<void> {
115     return this.config.update(key, value, true);
116   }
117
118   // helpers
119   public getExtensionName(): string {
120     return this.pkg.name;
121   }
122
123   public getExtensionId(): string {
124     return [this.pkg.publisher, this.pkg.name].join(".");
125   }
126
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);
131   }
132
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
137       homedir()
138     );
139
140     return Uri.file(fsPath);
141   }
142 }
This page took 0.032388 seconds and 4 git commands to generate.