]> Git Repo - pico-vscode.git/blob - src/settings.mts
FIX #73, cd command need '/d' option on Windows (cmd.exe). (#74)
[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   useCmakeTools = "useCmakeTools",
16 }
17
18 /**
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.
21  */
22 export const HOME_VAR = "${HOME}";
23
24 export type Setting = string | boolean | string[] | null | undefined;
25
26 export interface PackageJSON {
27   name: string;
28   publisher: string;
29 }
30
31 export type GlobalStateType = Memento & {
32   setKeysForSync(keys: readonly string[]): void;
33 };
34
35 const LAST_PROJECT_ROOT_STATE_KEY = "lastProjectRoot";
36
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;
43
44   private constructor(
45     workspaceState: Memento,
46     globalState: GlobalStateType,
47     packageJSON: PackageJSON
48   ) {
49     this.workspaceState = workspaceState;
50     this.globalState = globalState;
51     this.pkg = packageJSON;
52
53     this.config = workspace.getConfiguration(packageJSON.name);
54   }
55
56   public static createInstance(
57     workspaceState: Memento,
58     globalState: GlobalStateType,
59     packageJSON: PackageJSON
60   ): Settings {
61     Settings.instance = new Settings(workspaceState, globalState, packageJSON);
62
63     return Settings.instance;
64   }
65
66   public static getInstance(): Settings | undefined {
67     // TODO: maybe remove to increase performance
68     Settings.instance?.reload();
69
70     return Settings.instance;
71   }
72
73   public reload(): void {
74     this.config = workspace.getConfiguration(this.pkg.name);
75   }
76
77   public get(key: SettingsKey): Setting {
78     return this.config.get(key);
79   }
80
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) {
86       return undefined;
87     }
88
89     return value as T;
90   }
91
92   public getString(key: SettingsKey): string | undefined {
93     const value = this.get(key);
94
95     return typeof value === "string" ? value : undefined;
96   }
97
98   public getBoolean(key: SettingsKey): boolean | undefined {
99     const value = this.get(key);
100
101     return typeof value === "boolean" ? value : undefined;
102   }
103
104   public getArray(key: SettingsKey): string[] | undefined {
105     const value = this.get(key);
106
107     return Array.isArray(value) ? value : undefined;
108   }
109
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);
113   }
114
115   public updateGlobal<T>(key: SettingsKey, value: T): Thenable<void> {
116     return this.config.update(key, value, true);
117   }
118
119   // helpers
120   public getExtensionName(): string {
121     return this.pkg.name;
122   }
123
124   public getExtensionId(): string {
125     return [this.pkg.publisher, this.pkg.name].join(".");
126   }
127
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);
132   }
133
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
138       homedir()
139     );
140
141     return Uri.file(fsPath);
142   }
143 }
This page took 0.033427 seconds and 4 git commands to generate.