|
|
- 'use strict';
- export * from './config';
-
- import {
- ConfigurationChangeEvent,
- ConfigurationTarget,
- Event,
- EventEmitter,
- ExtensionContext,
- Uri,
- workspace
- } from 'vscode';
- import { Config } from './config';
- import { extensionId } from './constants';
- import { Objects } from './system';
-
- const emptyConfig: Config = new Proxy<Config>({} as Config, {
- get: function() {
- return emptyConfig;
- }
- });
-
- type ConfigInspection<T> = {
- key: string;
- defaultValue?: T;
- globalValue?: T;
- workspaceValue?: T;
- workspaceFolderValue?: T;
- };
-
- export interface ConfigurationWillChangeEvent {
- change: ConfigurationChangeEvent;
- transform?(e: ConfigurationChangeEvent): ConfigurationChangeEvent;
- }
-
- export class Configuration {
- static configure(context: ExtensionContext) {
- context.subscriptions.push(
- workspace.onDidChangeConfiguration(configuration.onConfigurationChanged, configuration)
- );
- }
-
- private _onDidChange = new EventEmitter<ConfigurationChangeEvent>();
- get onDidChange(): Event<ConfigurationChangeEvent> {
- return this._onDidChange.event;
- }
-
- private _onDidChangeAny = new EventEmitter<ConfigurationChangeEvent>();
- get onDidChangeAny(): Event<ConfigurationChangeEvent> {
- return this._onDidChange.event;
- }
-
- private _onWillChange = new EventEmitter<ConfigurationWillChangeEvent>();
- get onWillChange(): Event<ConfigurationWillChangeEvent> {
- return this._onWillChange.event;
- }
-
- private onConfigurationChanged(e: ConfigurationChangeEvent) {
- if (!e.affectsConfiguration(extensionId, null!)) {
- this._onDidChangeAny.fire(e);
-
- return;
- }
-
- const evt: ConfigurationWillChangeEvent = {
- change: e
- };
- this._onWillChange.fire(evt);
-
- if (evt.transform !== undefined) {
- e = evt.transform(e);
- }
-
- this._onDidChange.fire(e);
- }
-
- readonly initializingChangeEvent: ConfigurationChangeEvent = {
- affectsConfiguration: (section: string, resource?: Uri) => true
- };
-
- get(): Config;
- get<S1 extends keyof Config>(s1: S1, resource?: Uri | null, defaultValue?: Config[S1]): Config[S1];
- get<S1 extends keyof Config, S2 extends keyof Config[S1]>(
- s1: S1,
- s2: S2,
- resource?: Uri | null,
- defaultValue?: Config[S1][S2]
- ): Config[S1][S2];
- get<S1 extends keyof Config, S2 extends keyof Config[S1], S3 extends keyof Config[S1][S2]>(
- s1: S1,
- s2: S2,
- s3: S3,
- resource?: Uri | null,
- defaultValue?: Config[S1][S2][S3]
- ): Config[S1][S2][S3];
- get<
- S1 extends keyof Config,
- S2 extends keyof Config[S1],
- S3 extends keyof Config[S1][S2],
- S4 extends keyof Config[S1][S2][S3]
- >(
- s1: S1,
- s2: S2,
- s3: S3,
- s4: S4,
- resource?: Uri | null,
- defaultValue?: Config[S1][S2][S3][S4]
- ): Config[S1][S2][S3][S4];
- get<T>(...args: any[]): T {
- let section: string | undefined;
- let resource: Uri | null | undefined;
- let defaultValue: T | undefined;
- if (args.length > 0) {
- section = args[0];
- if (typeof args[1] === 'string') {
- section += `.${args[1]}`;
- if (typeof args[2] === 'string') {
- section += `.${args[2]}`;
- if (typeof args[2] === 'string') {
- section += `.${args[3]}`;
- resource = args[4];
- defaultValue = args[5];
- } else {
- resource = args[3];
- defaultValue = args[4];
- }
- } else {
- resource = args[2];
- defaultValue = args[3];
- }
- } else {
- resource = args[1];
- defaultValue = args[2];
- }
- }
-
- return defaultValue === undefined
- ? workspace
- .getConfiguration(section === undefined ? undefined : extensionId, resource)
- .get<T>(section === undefined ? extensionId : section)!
- : workspace
- .getConfiguration(section === undefined ? undefined : extensionId, resource)
- .get<T>(section === undefined ? extensionId : section, defaultValue)!;
- }
-
- getAny<T>(section: string, resource?: Uri | null, defaultValue?: T) {
- return defaultValue === undefined
- ? workspace.getConfiguration(undefined, resource).get<T>(section)!
- : workspace.getConfiguration(undefined, resource).get<T>(section, defaultValue)!;
- }
-
- changed<S1 extends keyof Config>(e: ConfigurationChangeEvent, s1: S1, resource?: Uri | null): boolean;
- changed<S1 extends keyof Config, S2 extends keyof Config[S1]>(
- e: ConfigurationChangeEvent,
- s1: S1,
- s2: S2,
- resource?: Uri | null
- ): boolean;
- changed<S1 extends keyof Config, S2 extends keyof Config[S1], S3 extends keyof Config[S1][S2]>(
- e: ConfigurationChangeEvent,
- s1: S1,
- s2: S2,
- s3: S3,
- resource?: Uri | null
- ): boolean;
- changed<
- S1 extends keyof Config,
- S2 extends keyof Config[S1],
- S3 extends keyof Config[S1][S2],
- S4 extends keyof Config[S1][S2][S3]
- >(e: ConfigurationChangeEvent, s1: S1, s2: S2, s3: S3, s4: S4, resource?: Uri | null): boolean;
- changed(e: ConfigurationChangeEvent, ...args: any[]) {
- let section: string = args[0];
- let resource: Uri | null | undefined;
- if (typeof args[1] === 'string') {
- section += `.${args[1]}`;
- if (typeof args[2] === 'string') {
- section += `.${args[2]}`;
- if (typeof args[3] === 'string') {
- section += args[3];
- resource = args[4];
- } else {
- resource = args[3];
- }
- } else {
- resource = args[2];
- }
- } else {
- resource = args[1];
- }
-
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
- return e.affectsConfiguration(`${extensionId}.${section}`, resource!);
- }
-
- initializing(e: ConfigurationChangeEvent) {
- return e === this.initializingChangeEvent;
- }
-
- inspect<S1 extends keyof Config>(s1: S1, resource?: Uri | null): ConfigInspection<Config[S1]> | undefined;
- inspect<S1 extends keyof Config, S2 extends keyof Config[S1]>(
- s1: S1,
- s2: S2,
- resource?: Uri | null
- ): ConfigInspection<Config[S1][S2]> | undefined;
- inspect<S1 extends keyof Config, S2 extends keyof Config[S1], S3 extends keyof Config[S1][S2]>(
- s1: S1,
- s2: S2,
- s3: S3,
- resource?: Uri | null
- ): ConfigInspection<Config[S1][S2][S3]> | undefined;
- inspect<
- S1 extends keyof Config,
- S2 extends keyof Config[S1],
- S3 extends keyof Config[S1][S2],
- S4 extends keyof Config[S1][S2][S3]
- >(s1: S1, s2: S2, s3: S3, s4: S4, resource?: Uri | null): ConfigInspection<Config[S1][S2][S3][S4]> | undefined;
- inspect(...args: any[]) {
- let section: string = args[0];
- let resource: Uri | null | undefined;
- if (typeof args[1] === 'string') {
- section += `.${args[1]}`;
- if (typeof args[2] === 'string') {
- section += `.${args[2]}`;
- if (typeof args[3] === 'string') {
- section += args[3];
- resource = args[4];
- } else {
- resource = args[3];
- }
- } else {
- resource = args[2];
- }
- } else {
- resource = args[1];
- }
-
- return workspace
- .getConfiguration(section === undefined ? undefined : extensionId, resource)
- .inspect(section === undefined ? extensionId : section);
- }
-
- inspectAny(section: string, resource?: Uri | null) {
- return workspace.getConfiguration(undefined, resource).inspect(section);
- }
-
- migrate<S1 extends keyof Config>(
- from: string,
- to1: S1,
- options: { fallbackValue?: Config[S1]; migrationFn?(value: any): Config[S1] }
- ): Promise<boolean>;
- migrate<S1 extends keyof Config, S2 extends keyof Config[S1]>(
- from: string,
- to1: S1,
- to2: S2,
- options: { fallbackValue?: Config[S1][S2]; migrationFn?(value: any): Config[S1][S2] }
- ): Promise<boolean>;
- migrate<S1 extends keyof Config, S2 extends keyof Config[S1], S3 extends keyof Config[S1][S2]>(
- from: string,
- to1: S1,
- to2: S2,
- to3: S3,
- options: { fallbackValue?: Config[S1][S2][S3]; migrationFn?(value: any): Config[S1][S2][S3] }
- ): Promise<boolean>;
- migrate<
- S1 extends keyof Config,
- S2 extends keyof Config[S1],
- S3 extends keyof Config[S1][S2],
- S4 extends keyof Config[S1][S2][S3]
- >(
- from: string,
- to1: S1,
- to2: S2,
- to3: S3,
- to4: S4,
- options: { fallbackValue?: Config[S1][S2][S3][S4]; migrationFn?(value: any): Config[S1][S2][S3][S4] }
- ): Promise<boolean>;
- async migrate(from: string, ...args: any[]): Promise<boolean> {
- let to: string = args[0];
- let options: { fallbackValue?: any; migrationFn?(value: any): any } | undefined;
- if (typeof args[1] === 'string' && args.length > 3) {
- to += `.${args[1]}`;
- if (typeof args[2] === 'string' && args.length > 4) {
- to += `.${args[2]}`;
- if (typeof args[3] === 'string' && args.length > 5) {
- to += `.${args[3]}`;
- options = args[4];
- } else {
- options = args[3];
- }
- } else {
- options = args[2];
- }
- } else {
- options = args[1];
- }
-
- if (options === undefined) {
- options = {};
- }
-
- const inspection = configuration.inspect(from as any);
- if (inspection === undefined) return false;
-
- let migrated = false;
- if (inspection.globalValue !== undefined) {
- await this.update(
- to as any,
- options.migrationFn ? options.migrationFn(inspection.globalValue) : inspection.globalValue,
- ConfigurationTarget.Global
- );
- migrated = true;
- // Can't delete the old setting currently because it errors with `Unable to write to User Settings because <setting name> is not a registered configuration`
- // if (from !== to) {
- // try {
- // await this.update(from, undefined, ConfigurationTarget.Global);
- // }
- // catch { }
- // }
- }
-
- if (inspection.workspaceValue !== undefined) {
- await this.update(
- to as any,
- options.migrationFn ? options.migrationFn(inspection.workspaceValue) : inspection.workspaceValue,
- ConfigurationTarget.Workspace
- );
- migrated = true;
- // Can't delete the old setting currently because it errors with `Unable to write to User Settings because <setting name> is not a registered configuration`
- // if (from !== to) {
- // try {
- // await this.update(from, undefined, ConfigurationTarget.Workspace);
- // }
- // catch { }
- // }
- }
-
- if (inspection.workspaceFolderValue !== undefined) {
- await this.update(
- to as any,
- options.migrationFn
- ? options.migrationFn(inspection.workspaceFolderValue)
- : inspection.workspaceFolderValue,
- ConfigurationTarget.WorkspaceFolder
- );
- migrated = true;
- // Can't delete the old setting currently because it errors with `Unable to write to User Settings because <setting name> is not a registered configuration`
- // if (from !== to) {
- // try {
- // await this.update(from, undefined, ConfigurationTarget.WorkspaceFolder);
- // }
- // catch { }
- // }
- }
-
- if (!migrated && options.fallbackValue !== undefined) {
- await this.update(to as any, options.fallbackValue, ConfigurationTarget.Global);
- migrated = true;
- }
-
- return migrated;
- }
-
- migrateIfMissing<S1 extends keyof Config>(
- from: string,
- to1: S1,
- options: { migrationFn?(value: any): Config[S1] }
- ): Promise<void>;
- migrateIfMissing<S1 extends keyof Config, S2 extends keyof Config[S1]>(
- from: string,
- to1: S1,
- to2: S2,
- options: { migrationFn?(value: any): Config[S1][S2] }
- ): Promise<void>;
- migrateIfMissing<S1 extends keyof Config, S2 extends keyof Config[S1], S3 extends keyof Config[S1][S2]>(
- from: string,
- to1: S1,
- to2: S2,
- to3: S3,
- options: { migrationFn?(value: any): Config[S1][S2][S3] }
- ): Promise<void>;
- migrateIfMissing<
- S1 extends keyof Config,
- S2 extends keyof Config[S1],
- S3 extends keyof Config[S1][S2],
- S4 extends keyof Config[S1][S2][S3]
- >(
- from: string,
- to1: S1,
- to2: S2,
- to3: S3,
- to4: S4,
- options: { migrationFn?(value: any): Config[S1][S2][S3][S4] }
- ): Promise<void>;
- async migrateIfMissing(from: string, ...args: any[]): Promise<void> {
- let to: string = args[0];
- let options: { migrationFn?(value: any): any } | undefined;
- if (typeof args[1] === 'string' && args.length > 3) {
- to += `.${args[1]}`;
- if (typeof args[2] === 'string' && args.length > 4) {
- to += `.${args[2]}`;
- if (typeof args[3] === 'string' && args.length > 5) {
- to += `.${args[3]}`;
- options = args[4];
- } else {
- options = args[3];
- }
- } else {
- options = args[2];
- }
- } else {
- options = args[1];
- }
-
- if (options === undefined) {
- options = {};
- }
-
- // async migrateIfMissing<TFrom, TTo>(from: string, to: string, options: { migrationFn?(value: TFrom): TTo } = {}) {
- const fromInspection = configuration.inspect(from as any);
- if (fromInspection === undefined) return;
-
- const toInspection = configuration.inspect(to as any);
- if (fromInspection.globalValue !== undefined) {
- if (toInspection === undefined || toInspection.globalValue === undefined) {
- await this.update(
- to as any,
- options.migrationFn ? options.migrationFn(fromInspection.globalValue) : fromInspection.globalValue,
- ConfigurationTarget.Global
- );
- // Can't delete the old setting currently because it errors with `Unable to write to User Settings because <setting name> is not a registered configuration`
- // if (from !== to) {
- // try {
- // await this.update(from, undefined, ConfigurationTarget.Global);
- // }
- // catch { }
- // }
- }
- }
-
- if (fromInspection.workspaceValue !== undefined) {
- if (toInspection === undefined || toInspection.workspaceValue === undefined) {
- await this.update(
- to as any,
- options.migrationFn
- ? options.migrationFn(fromInspection.workspaceValue)
- : fromInspection.workspaceValue,
- ConfigurationTarget.Workspace
- );
- // Can't delete the old setting currently because it errors with `Unable to write to User Settings because <setting name> is not a registered configuration`
- // if (from !== to) {
- // try {
- // await this.update(from, undefined, ConfigurationTarget.Workspace);
- // }
- // catch { }
- // }
- }
- }
-
- if (fromInspection.workspaceFolderValue !== undefined) {
- if (toInspection === undefined || toInspection.workspaceFolderValue === undefined) {
- await this.update(
- to as any,
- options.migrationFn
- ? options.migrationFn(fromInspection.workspaceFolderValue)
- : fromInspection.workspaceFolderValue,
- ConfigurationTarget.WorkspaceFolder
- );
- // Can't delete the old setting currently because it errors with `Unable to write to User Settings because <setting name> is not a registered configuration`
- // if (from !== to) {
- // try {
- // await this.update(from, undefined, ConfigurationTarget.WorkspaceFolder);
- // }
- // catch { }
- // }
- }
- }
- }
-
- name<S1 extends keyof Config>(s1: S1): string;
- name<S1 extends keyof Config, S2 extends keyof Config[S1]>(s1: S1, s2: S2): string;
- name<S1 extends keyof Config, S2 extends keyof Config[S1], S3 extends keyof Config[S1][S2]>(
- s1: S1,
- s2: S2,
- s3: S3
- ): string;
- name<
- S1 extends keyof Config,
- S2 extends keyof Config[S1],
- S3 extends keyof Config[S1][S2],
- S4 extends keyof Config[S1][S2][S3]
- >(s1: S1, s2: S2, s3: S3, s4: S4): string;
- name(...args: string[]) {
- return args.join('.');
- }
-
- update<S1 extends keyof Config>(s1: S1, value: Config[S1] | undefined, target: ConfigurationTarget): Thenable<void>;
- update<S1 extends keyof Config, S2 extends keyof Config[S1]>(
- s1: S1,
- s2: S2,
- value: Config[S1][S2] | undefined,
- target: ConfigurationTarget
- ): Thenable<void>;
-
- update<S1 extends keyof Config, S2 extends keyof Config[S1], S3 extends keyof Config[S1][S2]>(
- s1: S1,
- s2: S2,
- s3: S3,
- value: Config[S1][S2][S3] | undefined,
- target: ConfigurationTarget
- ): Thenable<void>;
- update<
- S1 extends keyof Config,
- S2 extends keyof Config[S1],
- S3 extends keyof Config[S1][S2],
- S4 extends keyof Config[S1][S2][S3]
- >(
- s1: S1,
- s2: S2,
- s3: S3,
- s4: S4,
- value: Config[S1][S2][S3][S4] | undefined,
- target: ConfigurationTarget
- ): Thenable<void>;
- update(...args: any[]) {
- let section: string = args[0];
- let value;
- let target: ConfigurationTarget;
- if (typeof args[1] === 'string' && args.length > 3) {
- section += `.${args[1]}`;
- if (typeof args[2] === 'string' && args.length > 4) {
- section += `.${args[2]}`;
- if (typeof args[3] === 'string' && args.length > 5) {
- section += `.${args[3]}`;
- value = args[4];
- target = args[5];
- } else {
- value = args[3];
- target = args[4];
- }
- } else {
- value = args[2];
- target = args[3];
- }
- } else {
- value = args[1];
- target = args[2];
- }
-
- return workspace.getConfiguration(extensionId).update(section, value, target);
- }
-
- updateAny(section: string, value: any, target: ConfigurationTarget, resource?: Uri | null) {
- return workspace
- .getConfiguration(undefined, target === ConfigurationTarget.Global ? undefined : resource!)
- .update(section, value, target);
- }
-
- updateEffective<S1 extends keyof Config>(s1: S1, value: Config[S1]): Thenable<void>;
- updateEffective<S1 extends keyof Config, S2 extends keyof Config[S1]>(
- s1: S1,
- s2: S2,
- value: Config[S1][S2]
- ): Thenable<void>;
- updateEffective<S1 extends keyof Config, S2 extends keyof Config[S1], S3 extends keyof Config[S1][S2]>(
- s1: S1,
- s2: S2,
- s3: S3,
- value: Config[S1][S2][S3]
- ): Thenable<void>;
- updateEffective<
- S1 extends keyof Config,
- S2 extends keyof Config[S1],
- S3 extends keyof Config[S1][S2],
- S4 extends keyof Config[S1][S2][S3]
- >(s1: S1, s2: S2, s3: S3, s4: S4, value: Config[S1][S2][S3][S4]): Thenable<void>;
- updateEffective(...args: any[]) {
- let section: string = args[0];
- let value;
- if (typeof args[1] === 'string' && args.length > 2) {
- section += `.${args[1]}`;
- if (typeof args[2] === 'string' && args.length > 3) {
- section += `.${args[2]}`;
- if (typeof args[3] === 'string' && args.length > 4) {
- section += `.${args[3]}`;
- value = args[4];
- } else {
- value = args[3];
- }
- } else {
- value = args[2];
- }
- } else {
- value = args[1];
- }
-
- const inspect = configuration.inspect(section as any)!;
- if (inspect.workspaceFolderValue !== undefined) {
- if (value === inspect.workspaceFolderValue) return Promise.resolve(undefined);
-
- return configuration.update(section as any, value, ConfigurationTarget.WorkspaceFolder);
- }
-
- if (inspect.workspaceValue !== undefined) {
- if (value === inspect.workspaceValue) return Promise.resolve(undefined);
-
- return configuration.update(section as any, value, ConfigurationTarget.Workspace);
- }
-
- if (inspect.globalValue === value || (inspect.globalValue === undefined && value === inspect.defaultValue)) {
- return Promise.resolve(undefined);
- }
-
- return configuration.update(
- section as any,
- Objects.areEquivalent(value, inspect.defaultValue) ? undefined : value,
- ConfigurationTarget.Global
- );
- }
- }
-
- export const configuration = new Configuration();
|