Skip to content

Commit

Permalink
feat: add Configuration class
Browse files Browse the repository at this point in the history
  • Loading branch information
tomgao365 committed Jun 10, 2024
1 parent 3f9922e commit 3e68bf3
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 3 deletions.
13 changes: 12 additions & 1 deletion examples/vscode-i18n/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,18 @@
"title": "%tomjs.commands.hello%",
"category": "%displayName%"
}
]
],
"configuration": {
"type": "object",
"title": "%displayName%",
"properties": {
"tomjs.xxx.hello": {
"type": "string",
"default": "Hello World",
"description": "%description%"
}
}
}
},
"icon": "resources/logo.png",
"vsce": {
Expand Down
21 changes: 19 additions & 2 deletions examples/vscode-i18n/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { getDotVSCodePath, getUserDataPath, i18n, initExtension } from '@tomjs/vscode';
import {
Configuration,
getDotVSCodePath,
getUserDataPath,
i18n,
initExtension,
} from '@tomjs/vscode';
import type { ExtensionContext } from 'vscode';
import { commands, window } from 'vscode';

export function activate(context: ExtensionContext) {
interface IConfig {
hello?: string;
}

export async function activate(context: ExtensionContext) {
initExtension(context);

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

console.log('user data path:', getUserDataPath());
console.log('.vscode path:', getDotVSCodePath());

const config = new Configuration<IConfig>('tomjs.xxx');
console.log('values:', config.values());
await config.update('hello', {
time: Date.now(),
});
console.log('values:', config.values());
}

export function deactivate() {}
90 changes: 90 additions & 0 deletions packages/vscode/src/configuration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { ConfigurationTarget, workspace } from 'vscode';

export class Configuration<T> {
private _defaultValues: T = {} as T;
private _values: T = {} as T;
private identifier: string;
constructor(identifier: string, defaultValues?: T) {
this.identifier = identifier;
this._defaultValues = Object.assign({}, defaultValues);
}

configuration() {
return workspace.getConfiguration(this.identifier);
}

/**
* Return a value from this configuration.
* @param section — Configuration name, supports dotted names.
* @param defaultValue — A value should be returned when no value could be found, is undefined.
* @returns — The value section denotes or the default.
*/
get<T>(section: string): T | undefined;
get<T>(section: string, defaultValue: T): T | undefined;
get<T>(section: string, defaultValue?: T): T | undefined {
return this.configuration().get(section, defaultValue ?? this._defaultValues[section]);
}

/**
* Get all Configuration values.
*/
values(): T {
const values = Object.assign({});
const cfg = this.configuration();
Object.keys(cfg)
.filter(key => typeof cfg[key] !== 'function')
.forEach(key => {
values[key] = cfg.get(key, this._defaultValues[key]);
});
return values;
}

/**
* Update a configuration value. The updated configuration values are persisted.
* @param section Configuration name, supports dotted names.
* @param value The new value.
* @param target The {@link ConfigurationTarget configuration target} or a boolean value. Defaults to `true`
* - If `true` updates {@link ConfigurationTarget.Global Global settings}.
* - If `false` updates {@link ConfigurationTarget.Workspace Workspace settings}.
* - If `undefined` or `null` updates to {@link ConfigurationTarget.WorkspaceFolder Workspace folder settings} if configuration is resource specific,
* otherwise to {@link ConfigurationTarget.Workspace Workspace settings}.
*/
async update(
section: string,
value: any,
target?: ConfigurationTarget | boolean | null,
): Promise<void>;

/**
* Update configuration values. The updated configuration values are persisted.
* @param values Configuration names and values, supports dotted names.
* @param target The {@link ConfigurationTarget configuration target} or a boolean value. Defaults to `true`
* - If `true` updates {@link ConfigurationTarget.Global Global settings}.
* - If `false` updates {@link ConfigurationTarget.Workspace Workspace settings}.
* - If `undefined` or `null` updates to {@link ConfigurationTarget.WorkspaceFolder Workspace folder settings} if configuration is resource specific,
* otherwise to {@link ConfigurationTarget.Workspace Workspace settings}.
*/
async update(values: T, target?: ConfigurationTarget | boolean | null): Promise<void>;
async update(section: string | T, value: any, target?: ConfigurationTarget | boolean | null) {
const values: any = {};
let _target: ConfigurationTarget | boolean | undefined | null;
if (typeof section === 'string') {
values[section] = value;
_target = target;
} else if (typeof section === 'object') {
Object.assign(values, section);
_target = value;
} else {
throw new Error('');
}

const cfg = this.configuration();
await Promise.all(
Object.keys(values).map(key =>
cfg.update(key, values[key], _target ?? ConfigurationTarget.Global).then(() => {
this._values[key] = values[key];
}),
),
);
}
}
1 change: 1 addition & 0 deletions packages/vscode/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { ExtensionContext } from 'vscode';
import { setExtensionContext } from './ctx';
import { loadI18n } from './i18n';

export * from './configuration';
export * from './constants';
export * from './ctx';
export * from './i18n';
Expand Down

0 comments on commit 3e68bf3

Please sign in to comment.