Skip to content

Commit 3e68bf3

Browse files
committed
feat: add Configuration class
1 parent 3f9922e commit 3e68bf3

File tree

4 files changed

+122
-3
lines changed

4 files changed

+122
-3
lines changed

examples/vscode-i18n/package.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,18 @@
2525
"title": "%tomjs.commands.hello%",
2626
"category": "%displayName%"
2727
}
28-
]
28+
],
29+
"configuration": {
30+
"type": "object",
31+
"title": "%displayName%",
32+
"properties": {
33+
"tomjs.xxx.hello": {
34+
"type": "string",
35+
"default": "Hello World",
36+
"description": "%description%"
37+
}
38+
}
39+
}
2940
},
3041
"icon": "resources/logo.png",
3142
"vsce": {

examples/vscode-i18n/src/index.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1-
import { getDotVSCodePath, getUserDataPath, i18n, initExtension } from '@tomjs/vscode';
1+
import {
2+
Configuration,
3+
getDotVSCodePath,
4+
getUserDataPath,
5+
i18n,
6+
initExtension,
7+
} from '@tomjs/vscode';
28
import type { ExtensionContext } from 'vscode';
39
import { commands, window } from 'vscode';
410

5-
export function activate(context: ExtensionContext) {
11+
interface IConfig {
12+
hello?: string;
13+
}
14+
15+
export async function activate(context: ExtensionContext) {
616
initExtension(context);
717

818
context.subscriptions.push(
@@ -13,6 +23,13 @@ export function activate(context: ExtensionContext) {
1323

1424
console.log('user data path:', getUserDataPath());
1525
console.log('.vscode path:', getDotVSCodePath());
26+
27+
const config = new Configuration<IConfig>('tomjs.xxx');
28+
console.log('values:', config.values());
29+
await config.update('hello', {
30+
time: Date.now(),
31+
});
32+
console.log('values:', config.values());
1633
}
1734

1835
export function deactivate() {}

packages/vscode/src/configuration.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { ConfigurationTarget, workspace } from 'vscode';
2+
3+
export class Configuration<T> {
4+
private _defaultValues: T = {} as T;
5+
private _values: T = {} as T;
6+
private identifier: string;
7+
constructor(identifier: string, defaultValues?: T) {
8+
this.identifier = identifier;
9+
this._defaultValues = Object.assign({}, defaultValues);
10+
}
11+
12+
configuration() {
13+
return workspace.getConfiguration(this.identifier);
14+
}
15+
16+
/**
17+
* Return a value from this configuration.
18+
* @param section — Configuration name, supports dotted names.
19+
* @param defaultValue — A value should be returned when no value could be found, is undefined.
20+
* @returns — The value section denotes or the default.
21+
*/
22+
get<T>(section: string): T | undefined;
23+
get<T>(section: string, defaultValue: T): T | undefined;
24+
get<T>(section: string, defaultValue?: T): T | undefined {
25+
return this.configuration().get(section, defaultValue ?? this._defaultValues[section]);
26+
}
27+
28+
/**
29+
* Get all Configuration values.
30+
*/
31+
values(): T {
32+
const values = Object.assign({});
33+
const cfg = this.configuration();
34+
Object.keys(cfg)
35+
.filter(key => typeof cfg[key] !== 'function')
36+
.forEach(key => {
37+
values[key] = cfg.get(key, this._defaultValues[key]);
38+
});
39+
return values;
40+
}
41+
42+
/**
43+
* Update a configuration value. The updated configuration values are persisted.
44+
* @param section Configuration name, supports dotted names.
45+
* @param value The new value.
46+
* @param target The {@link ConfigurationTarget configuration target} or a boolean value. Defaults to `true`
47+
* - If `true` updates {@link ConfigurationTarget.Global Global settings}.
48+
* - If `false` updates {@link ConfigurationTarget.Workspace Workspace settings}.
49+
* - If `undefined` or `null` updates to {@link ConfigurationTarget.WorkspaceFolder Workspace folder settings} if configuration is resource specific,
50+
* otherwise to {@link ConfigurationTarget.Workspace Workspace settings}.
51+
*/
52+
async update(
53+
section: string,
54+
value: any,
55+
target?: ConfigurationTarget | boolean | null,
56+
): Promise<void>;
57+
58+
/**
59+
* Update configuration values. The updated configuration values are persisted.
60+
* @param values Configuration names and values, supports dotted names.
61+
* @param target The {@link ConfigurationTarget configuration target} or a boolean value. Defaults to `true`
62+
* - If `true` updates {@link ConfigurationTarget.Global Global settings}.
63+
* - If `false` updates {@link ConfigurationTarget.Workspace Workspace settings}.
64+
* - If `undefined` or `null` updates to {@link ConfigurationTarget.WorkspaceFolder Workspace folder settings} if configuration is resource specific,
65+
* otherwise to {@link ConfigurationTarget.Workspace Workspace settings}.
66+
*/
67+
async update(values: T, target?: ConfigurationTarget | boolean | null): Promise<void>;
68+
async update(section: string | T, value: any, target?: ConfigurationTarget | boolean | null) {
69+
const values: any = {};
70+
let _target: ConfigurationTarget | boolean | undefined | null;
71+
if (typeof section === 'string') {
72+
values[section] = value;
73+
_target = target;
74+
} else if (typeof section === 'object') {
75+
Object.assign(values, section);
76+
_target = value;
77+
} else {
78+
throw new Error('');
79+
}
80+
81+
const cfg = this.configuration();
82+
await Promise.all(
83+
Object.keys(values).map(key =>
84+
cfg.update(key, values[key], _target ?? ConfigurationTarget.Global).then(() => {
85+
this._values[key] = values[key];
86+
}),
87+
),
88+
);
89+
}
90+
}

packages/vscode/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { ExtensionContext } from 'vscode';
22
import { setExtensionContext } from './ctx';
33
import { loadI18n } from './i18n';
44

5+
export * from './configuration';
56
export * from './constants';
67
export * from './ctx';
78
export * from './i18n';

0 commit comments

Comments
 (0)