mirror of
https://github.com/Microsoft/vscode
synced 2024-10-04 02:14:06 +00:00
#51935 support updating configuration for multiple language identifiers in configuration service
This commit is contained in:
parent
7131e48daf
commit
f6470973e7
|
@ -25,6 +25,16 @@ export interface IConfigurationOverrides {
|
|||
resource?: URI | null;
|
||||
}
|
||||
|
||||
export function isConfigurationUpdateOverrides(thing: any): thing is IConfigurationUpdateOverrides {
|
||||
return thing
|
||||
&& typeof thing === 'object'
|
||||
&& (!thing.overrideIdentifiers || types.isArray(thing.overrideIdentifiers))
|
||||
&& !thing.overrideIdentifier
|
||||
&& (!thing.resource || thing.resource instanceof URI);
|
||||
}
|
||||
|
||||
export type IConfigurationUpdateOverrides = Omit<IConfigurationOverrides, 'overrideIdentifier'> & { overrideIdentifiers?: string[] | null; };
|
||||
|
||||
export const enum ConfigurationTarget {
|
||||
USER = 1,
|
||||
USER_LOCAL,
|
||||
|
@ -106,9 +116,9 @@ export interface IConfigurationService {
|
|||
getValue<T>(section: string, overrides: IConfigurationOverrides): T;
|
||||
|
||||
updateValue(key: string, value: any): Promise<void>;
|
||||
updateValue(key: string, value: any, overrides: IConfigurationOverrides): Promise<void>;
|
||||
updateValue(key: string, value: any, overrides: IConfigurationOverrides | IConfigurationUpdateOverrides): Promise<void>;
|
||||
updateValue(key: string, value: any, target: ConfigurationTarget): Promise<void>;
|
||||
updateValue(key: string, value: any, overrides: IConfigurationOverrides, target: ConfigurationTarget, donotNotifyError?: boolean): Promise<void>;
|
||||
updateValue(key: string, value: any, overrides: IConfigurationOverrides | IConfigurationUpdateOverrides, target: ConfigurationTarget, donotNotifyError?: boolean): Promise<void>;
|
||||
|
||||
inspect<T>(key: string, overrides?: IConfigurationOverrides): IConfigurationValue<Readonly<T>>;
|
||||
|
||||
|
@ -269,10 +279,6 @@ export function getDefaultValues(): any {
|
|||
return valueTreeRoot;
|
||||
}
|
||||
|
||||
export function keyFromOverrideIdentifier(overrideIdentifier: string): string {
|
||||
return `[${overrideIdentifier}]`;
|
||||
}
|
||||
|
||||
export function getMigratedSettingValue<T>(configurationService: IConfigurationService, currentSettingName: string, legacySettingName: string): T {
|
||||
const setting = configurationService.inspect<T>(currentSettingName);
|
||||
const legacySetting = configurationService.inspect<T>(legacySettingName);
|
||||
|
|
|
@ -13,8 +13,8 @@ import * as objects from 'vs/base/common/objects';
|
|||
import { IExtUri } from 'vs/base/common/resources';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { addToValueTree, ConfigurationTarget, getConfigurationKeys, getConfigurationValue, getDefaultValues, IConfigurationChange, IConfigurationChangeEvent, IConfigurationCompareResult, IConfigurationData, IConfigurationModel, IConfigurationOverrides, IConfigurationValue, IOverrides, removeFromValueTree, toValuesTree } from 'vs/platform/configuration/common/configuration';
|
||||
import { ConfigurationScope, Extensions, IConfigurationPropertySchema, IConfigurationRegistry, overrideIdentifiersFromKey, OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { addToValueTree, ConfigurationTarget, getConfigurationKeys, getConfigurationValue, getDefaultValues, IConfigurationChange, IConfigurationChangeEvent, IConfigurationCompareResult, IConfigurationData, IConfigurationModel, IConfigurationOverrides, IConfigurationUpdateOverrides, IConfigurationValue, IOverrides, removeFromValueTree, toValuesTree } from 'vs/platform/configuration/common/configuration';
|
||||
import { ConfigurationScope, Extensions, IConfigurationPropertySchema, IConfigurationRegistry, overrideIdentifiersFromKey, OVERRIDE_PROPERTY_REGEX } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Workspace } from 'vs/platform/workspace/common/workspace';
|
||||
|
@ -239,7 +239,7 @@ export class DefaultConfigurationModel extends ConfigurationModel {
|
|||
const keys = getConfigurationKeys();
|
||||
const overrides: IOverrides[] = [];
|
||||
for (const key of Object.keys(contents)) {
|
||||
if (OVERRIDE_PROPERTY_PATTERN.test(key)) {
|
||||
if (OVERRIDE_PROPERTY_REGEX.test(key)) {
|
||||
overrides.push({
|
||||
identifiers: overrideIdentifiersFromKey(key),
|
||||
keys: Object.keys(contents[key]),
|
||||
|
@ -371,7 +371,7 @@ export class ConfigurationModelParser {
|
|||
const raw: any = {};
|
||||
const restricted: string[] = [];
|
||||
for (let key in properties) {
|
||||
if (OVERRIDE_PROPERTY_PATTERN.test(key) && filterOverriddenProperties) {
|
||||
if (OVERRIDE_PROPERTY_REGEX.test(key) && filterOverriddenProperties) {
|
||||
const result = this.filter(properties[key], configurationProperties, false, options);
|
||||
raw[key] = result.raw;
|
||||
restricted.push(...result.restricted);
|
||||
|
@ -395,7 +395,7 @@ export class ConfigurationModelParser {
|
|||
private toOverrides(raw: any, conflictReporter: (message: string) => void): IOverrides[] {
|
||||
const overrides: IOverrides[] = [];
|
||||
for (const key of Object.keys(raw)) {
|
||||
if (OVERRIDE_PROPERTY_PATTERN.test(key)) {
|
||||
if (OVERRIDE_PROPERTY_REGEX.test(key)) {
|
||||
const overrideRaw: any = {};
|
||||
for (const keyInOverrideRaw in raw[key]) {
|
||||
overrideRaw[keyInOverrideRaw] = raw[key][keyInOverrideRaw];
|
||||
|
@ -476,7 +476,7 @@ export class Configuration {
|
|||
return consolidateConfigurationModel.getValue(section);
|
||||
}
|
||||
|
||||
updateValue(key: string, value: any, overrides: IConfigurationOverrides = {}): void {
|
||||
updateValue(key: string, value: any, overrides: IConfigurationUpdateOverrides = {}): void {
|
||||
let memoryConfiguration: ConfigurationModel | undefined;
|
||||
if (overrides.resource) {
|
||||
memoryConfiguration = this._memoryConfigurationByResource.get(overrides.resource);
|
||||
|
|
|
@ -258,7 +258,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
for (const key in defaultConfiguration) {
|
||||
properties.push(key);
|
||||
|
||||
if (OVERRIDE_PROPERTY_PATTERN.test(key)) {
|
||||
if (OVERRIDE_PROPERTY_REGEX.test(key)) {
|
||||
this.defaultValues[key] = { ...(this.defaultValues[key] || {}), ...defaultConfiguration[key] };
|
||||
const property: IConfigurationPropertySchema = {
|
||||
type: 'object',
|
||||
|
@ -291,7 +291,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
for (const key in defaultConfiguration) {
|
||||
properties.push(key);
|
||||
delete this.defaultValues[key];
|
||||
if (OVERRIDE_PROPERTY_PATTERN.test(key)) {
|
||||
if (OVERRIDE_PROPERTY_REGEX.test(key)) {
|
||||
delete this.configurationProperties[key];
|
||||
delete this.defaultLanguageConfigurationOverridesNode.properties![key];
|
||||
} else {
|
||||
|
@ -371,7 +371,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
this.updatePropertyDefaultValue(key, property);
|
||||
|
||||
// update scope
|
||||
if (OVERRIDE_PROPERTY_PATTERN.test(key)) {
|
||||
if (OVERRIDE_PROPERTY_REGEX.test(key)) {
|
||||
property.scope = undefined; // No scope for overridable properties `[${identifier}]`
|
||||
} else {
|
||||
property.scope = types.isUndefinedOrNull(property.scope) ? scope : property.scope;
|
||||
|
@ -507,12 +507,12 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
errorMessage: nls.localize('overrideSettings.errorMessage', "This setting does not support per-language configuration."),
|
||||
$ref: resourceLanguageSettingsSchemaId,
|
||||
};
|
||||
allSettings.patternProperties[OVERRIDE_PROPERTY] = resourceLanguagePropertiesSchema;
|
||||
applicationSettings.patternProperties[OVERRIDE_PROPERTY] = resourceLanguagePropertiesSchema;
|
||||
machineSettings.patternProperties[OVERRIDE_PROPERTY] = resourceLanguagePropertiesSchema;
|
||||
machineOverridableSettings.patternProperties[OVERRIDE_PROPERTY] = resourceLanguagePropertiesSchema;
|
||||
windowSettings.patternProperties[OVERRIDE_PROPERTY] = resourceLanguagePropertiesSchema;
|
||||
resourceSettings.patternProperties[OVERRIDE_PROPERTY] = resourceLanguagePropertiesSchema;
|
||||
allSettings.patternProperties[OVERRIDE_PROPERTY_PATTERN] = resourceLanguagePropertiesSchema;
|
||||
applicationSettings.patternProperties[OVERRIDE_PROPERTY_PATTERN] = resourceLanguagePropertiesSchema;
|
||||
machineSettings.patternProperties[OVERRIDE_PROPERTY_PATTERN] = resourceLanguagePropertiesSchema;
|
||||
machineOverridableSettings.patternProperties[OVERRIDE_PROPERTY_PATTERN] = resourceLanguagePropertiesSchema;
|
||||
windowSettings.patternProperties[OVERRIDE_PROPERTY_PATTERN] = resourceLanguagePropertiesSchema;
|
||||
resourceSettings.patternProperties[OVERRIDE_PROPERTY_PATTERN] = resourceLanguagePropertiesSchema;
|
||||
this._onDidSchemaChange.fire();
|
||||
}
|
||||
|
||||
|
@ -528,26 +528,30 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
const OVERRIDE_IDENTIFIER = `\\[([^\\]]+)\\]`;
|
||||
const OVERRIDE_IDENTIFIER_PATTERN = new RegExp(OVERRIDE_IDENTIFIER, 'g');
|
||||
export const OVERRIDE_PROPERTY = `^(${OVERRIDE_IDENTIFIER})+$`;
|
||||
export const OVERRIDE_PROPERTY_PATTERN = new RegExp(OVERRIDE_PROPERTY);
|
||||
const OVERRIDE_IDENTIFIER_PATTERN = `\\[([^\\]]+)\\]`;
|
||||
const OVERRIDE_IDENTIFIER_REGEX = new RegExp(OVERRIDE_IDENTIFIER_PATTERN, 'g');
|
||||
export const OVERRIDE_PROPERTY_PATTERN = `^(${OVERRIDE_IDENTIFIER_PATTERN})+$`;
|
||||
export const OVERRIDE_PROPERTY_REGEX = new RegExp(OVERRIDE_PROPERTY_PATTERN);
|
||||
|
||||
export function overrideIdentifiersFromKey(key: string): string[] {
|
||||
const identifiers: string[] = [];
|
||||
if (OVERRIDE_PROPERTY_PATTERN.test(key)) {
|
||||
let matches = OVERRIDE_IDENTIFIER_PATTERN.exec(key);
|
||||
if (OVERRIDE_PROPERTY_REGEX.test(key)) {
|
||||
let matches = OVERRIDE_IDENTIFIER_REGEX.exec(key);
|
||||
while (matches?.length) {
|
||||
const identifier = matches[1].trim();
|
||||
if (identifier) {
|
||||
identifiers.push(identifier);
|
||||
}
|
||||
matches = OVERRIDE_IDENTIFIER_PATTERN.exec(key);
|
||||
matches = OVERRIDE_IDENTIFIER_REGEX.exec(key);
|
||||
}
|
||||
}
|
||||
return distinct(identifiers);
|
||||
}
|
||||
|
||||
export function keyFromOverrideIdentifiers(overrideIdentifiers: string[]): string {
|
||||
return overrideIdentifiers.reduce((result, overrideIdentifier) => `${result}[${overrideIdentifier}]`, '');
|
||||
}
|
||||
|
||||
export function getDefaultValue(type: string | string[] | undefined): any {
|
||||
const t = Array.isArray(type) ? (<string[]>type)[0] : <string>type;
|
||||
switch (t) {
|
||||
|
@ -567,7 +571,6 @@ export function getDefaultValue(type: string | string[] | undefined): any {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
const configurationRegistry = new ConfigurationRegistry();
|
||||
Registry.add(Extensions.Configuration, configurationRegistry);
|
||||
|
||||
|
@ -575,7 +578,7 @@ export function validateProperty(property: string): string | null {
|
|||
if (!property.trim()) {
|
||||
return nls.localize('config.property.empty', "Cannot register an empty property");
|
||||
}
|
||||
if (OVERRIDE_PROPERTY_PATTERN.test(property)) {
|
||||
if (OVERRIDE_PROPERTY_REGEX.test(property)) {
|
||||
return nls.localize('config.property.languageDefault', "Cannot register '{0}'. This matches property pattern '\\\\[.*\\\\]$' for describing language specific editor settings. Use 'configurationDefaults' contribution.", property);
|
||||
}
|
||||
if (configurationRegistry.getConfigurationProperties()[property] !== undefined) {
|
||||
|
|
|
@ -8,7 +8,7 @@ import * as objects from 'vs/base/common/objects';
|
|||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||
import { ExtensionsRegistry, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
||||
import { IConfigurationNode, IConfigurationRegistry, Extensions, resourceLanguageSettingsSchemaId, validateProperty, ConfigurationScope, OVERRIDE_PROPERTY_PATTERN, OVERRIDE_PROPERTY } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IConfigurationNode, IConfigurationRegistry, Extensions, resourceLanguageSettingsSchemaId, validateProperty, ConfigurationScope, OVERRIDE_PROPERTY_PATTERN, OVERRIDE_PROPERTY_REGEX } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
|
||||
import { workspaceSettingsSchemaId, launchSchemaId, tasksSchemaId } from 'vs/workbench/services/configuration/common/configuration';
|
||||
import { isObject } from 'vs/base/common/types';
|
||||
|
@ -110,7 +110,7 @@ const defaultConfigurationExtPoint = ExtensionsRegistry.registerExtensionPoint<I
|
|||
description: nls.localize('vscode.extension.contributes.defaultConfiguration', 'Contributes default editor configuration settings by language.'),
|
||||
type: 'object',
|
||||
patternProperties: {
|
||||
[OVERRIDE_PROPERTY]: {
|
||||
[OVERRIDE_PROPERTY_PATTERN]: {
|
||||
type: 'object',
|
||||
default: {},
|
||||
$ref: resourceLanguageSettingsSchemaId,
|
||||
|
@ -129,7 +129,7 @@ defaultConfigurationExtPoint.setHandler((extensions, { added, removed }) => {
|
|||
const addedDefaultConfigurations = added.map<IStringDictionary<any>>(extension => {
|
||||
const defaults: IStringDictionary<any> = objects.deepClone(extension.value);
|
||||
for (const key of Object.keys(defaults)) {
|
||||
if (!OVERRIDE_PROPERTY_PATTERN.test(key) || typeof defaults[key] !== 'object') {
|
||||
if (!OVERRIDE_PROPERTY_REGEX.test(key) || typeof defaults[key] !== 'object') {
|
||||
extension.collector.warn(nls.localize('config.property.defaultConfiguration.warning', "Cannot register configuration defaults for '{0}'. Only defaults for language specific settings are supported.", key));
|
||||
delete defaults[key];
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import { ExtHostConfigurationShape, MainThreadConfigurationShape, IConfiguration
|
|||
import { ConfigurationTarget as ExtHostConfigurationTarget } from './extHostTypes';
|
||||
import { ConfigurationTarget, IConfigurationChange, IConfigurationData, IConfigurationOverrides } from 'vs/platform/configuration/common/configuration';
|
||||
import { Configuration, ConfigurationChangeEvent } from 'vs/platform/configuration/common/configurationModels';
|
||||
import { ConfigurationScope, OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { ConfigurationScope, OVERRIDE_PROPERTY_REGEX } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { isObject } from 'vs/base/common/types';
|
||||
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { Barrier } from 'vs/base/common/async';
|
||||
|
@ -297,7 +297,7 @@ export class ExtHostConfigProvider {
|
|||
}
|
||||
|
||||
private _validateConfigurationAccess(key: string, overrides?: IConfigurationOverrides, extensionId?: ExtensionIdentifier): void {
|
||||
const scope = OVERRIDE_PROPERTY_PATTERN.test(key) ? ConfigurationScope.RESOURCE : this._configurationScopes.get(key);
|
||||
const scope = OVERRIDE_PROPERTY_REGEX.test(key) ? ConfigurationScope.RESOURCE : this._configurationScopes.get(key);
|
||||
const extensionIdText = extensionId ? `[${extensionId.value}] ` : '';
|
||||
if (ConfigurationScope.RESOURCE === scope) {
|
||||
if (typeof overrides?.resource === 'undefined') {
|
||||
|
|
|
@ -24,7 +24,7 @@ import * as modes from 'vs/editor/common/modes';
|
|||
import { CodeActionKind } from 'vs/editor/contrib/codeAction/types';
|
||||
import * as nls from 'vs/nls';
|
||||
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ConfigurationScope, Extensions as ConfigurationExtensions, IConfigurationPropertySchema, IConfigurationRegistry, OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { ConfigurationScope, Extensions as ConfigurationExtensions, IConfigurationPropertySchema, IConfigurationRegistry, overrideIdentifiersFromKey, OVERRIDE_PROPERTY_REGEX } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IMarkerData, IMarkerService, MarkerSeverity, MarkerTag } from 'vs/platform/markers/common/markers';
|
||||
|
@ -76,9 +76,9 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend
|
|||
}
|
||||
|
||||
updatePreference(key: string, value: any, source: IIndexedSetting): void {
|
||||
const overrideIdentifier = source.overrideOf ? source.overrideOf.key.substring(1, source.overrideOf.key.length - 1) : null;
|
||||
const overrideIdentifiers = source.overrideOf ? overrideIdentifiersFromKey(source.overrideOf.key) : null;
|
||||
const resource = this.preferencesModel.uri;
|
||||
this.configurationService.updateValue(key, value, { overrideIdentifier, resource }, this.preferencesModel.configurationTarget)
|
||||
this.configurationService.updateValue(key, value, { overrideIdentifiers, resource }, this.preferencesModel.configurationTarget)
|
||||
.then(() => this.onSettingUpdated(source));
|
||||
}
|
||||
|
||||
|
@ -533,7 +533,7 @@ class UnsupportedSettingsRenderer extends Disposable implements modes.CodeAction
|
|||
this.handleWorkspaceFolderConfiguration(setting, configuration, markerData);
|
||||
break;
|
||||
}
|
||||
} else if (!OVERRIDE_PROPERTY_PATTERN.test(setting.key)) { // Ignore override settings (language specific settings)
|
||||
} else if (!OVERRIDE_PROPERTY_REGEX.test(setting.key)) { // Ignore override settings (language specific settings)
|
||||
markerData.push({
|
||||
severity: MarkerSeverity.Hint,
|
||||
tags: [MarkerTag.Unnecessary],
|
||||
|
|
|
@ -12,11 +12,11 @@ import { Queue, Barrier, runWhenIdle, Promises } from 'vs/base/common/async';
|
|||
import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
|
||||
import { IWorkspaceContextService, Workspace as BaseWorkspace, WorkbenchState, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, WorkspaceFolder, toWorkspaceFolder, isWorkspaceFolder, IWorkspaceFoldersWillChangeEvent } from 'vs/platform/workspace/common/workspace';
|
||||
import { ConfigurationModel, DefaultConfigurationModel, ConfigurationChangeEvent, AllKeysConfigurationChangeEvent, mergeChanges } from 'vs/platform/configuration/common/configurationModels';
|
||||
import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, keyFromOverrideIdentifier, isConfigurationOverrides, IConfigurationData, IConfigurationValue, IConfigurationChange, ConfigurationTargetToString } from 'vs/platform/configuration/common/configuration';
|
||||
import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, isConfigurationOverrides, IConfigurationData, IConfigurationValue, IConfigurationChange, ConfigurationTargetToString, IConfigurationUpdateOverrides, isConfigurationUpdateOverrides } from 'vs/platform/configuration/common/configuration';
|
||||
import { Configuration } from 'vs/workbench/services/configuration/common/configurationModels';
|
||||
import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES, IWorkbenchConfigurationService, RestrictedSettings } from 'vs/workbench/services/configuration/common/configuration';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IConfigurationRegistry, Extensions, allSettings, windowSettings, resourceSettings, applicationSettings, machineSettings, machineOverridableSettings, ConfigurationScope, IConfigurationPropertySchema } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IConfigurationRegistry, Extensions, allSettings, windowSettings, resourceSettings, applicationSettings, machineSettings, machineOverridableSettings, ConfigurationScope, IConfigurationPropertySchema, keyFromOverrideIdentifiers } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, IWorkspaceInitializationPayload, IEmptyWorkspaceIdentifier, useSlashForPath, getStoredWorkspaceFolder, isSingleFolderWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, toWorkspaceFolders } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ConfigurationEditingService, EditableConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditingService';
|
||||
|
@ -305,18 +305,26 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat
|
|||
}
|
||||
|
||||
updateValue(key: string, value: any): Promise<void>;
|
||||
updateValue(key: string, value: any, overrides: IConfigurationOverrides): Promise<void>;
|
||||
updateValue(key: string, value: any, overrides: IConfigurationOverrides | IConfigurationUpdateOverrides): Promise<void>;
|
||||
updateValue(key: string, value: any, target: ConfigurationTarget): Promise<void>;
|
||||
updateValue(key: string, value: any, overrides: IConfigurationOverrides, target: ConfigurationTarget): Promise<void>;
|
||||
updateValue(key: string, value: any, overrides: IConfigurationOverrides, target: ConfigurationTarget, donotNotifyError: boolean): Promise<void>;
|
||||
updateValue(key: string, value: any, overrides: IConfigurationOverrides | IConfigurationUpdateOverrides, target: ConfigurationTarget, donotNotifyError?: boolean): Promise<void>;
|
||||
async updateValue(key: string, value: any, arg3?: any, arg4?: any, donotNotifyError?: any): Promise<void> {
|
||||
await this.cyclicDependency;
|
||||
const overrides = isConfigurationOverrides(arg3) ? arg3 : undefined;
|
||||
const overrides: IConfigurationUpdateOverrides | undefined = isConfigurationUpdateOverrides(arg3) ? arg3
|
||||
: isConfigurationOverrides(arg3) ? { resource: arg3.resource, overrideIdentifiers: arg3.overrideIdentifier ? [arg3.overrideIdentifier] : undefined } : undefined;
|
||||
const target: ConfigurationTarget | undefined = overrides ? arg4 : arg3;
|
||||
const targets: ConfigurationTarget[] = target ? [target] : [];
|
||||
|
||||
if (overrides?.overrideIdentifiers) {
|
||||
overrides.overrideIdentifiers = distinct(overrides.overrideIdentifiers);
|
||||
overrides.overrideIdentifiers = overrides.overrideIdentifiers.length ? overrides.overrideIdentifiers : undefined;
|
||||
}
|
||||
|
||||
if (!targets.length) {
|
||||
const inspect = this.inspect(key, overrides);
|
||||
if (overrides?.overrideIdentifiers && overrides.overrideIdentifiers.length > 1) {
|
||||
throw new Error('Configuration Target is required while updating the value for multiple override identifiers');
|
||||
}
|
||||
const inspect = this.inspect(key, { resource: overrides?.resource, overrideIdentifier: overrides?.overrideIdentifiers ? overrides.overrideIdentifiers[0] : undefined });
|
||||
targets.push(...this.deriveConfigurationTargets(key, value, inspect));
|
||||
|
||||
// Remove the setting, if the value is same as default value and is updated only in user target
|
||||
|
@ -856,7 +864,7 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat
|
|||
return validWorkspaceFolders;
|
||||
}
|
||||
|
||||
private async writeConfigurationValue(key: string, value: any, target: ConfigurationTarget, overrides: IConfigurationOverrides | undefined, donotNotifyError: boolean): Promise<void> {
|
||||
private async writeConfigurationValue(key: string, value: any, target: ConfigurationTarget, overrides: IConfigurationUpdateOverrides | undefined, donotNotifyError: boolean): Promise<void> {
|
||||
if (target === ConfigurationTarget.DEFAULT) {
|
||||
throw new Error('Invalid configuration target');
|
||||
}
|
||||
|
@ -864,7 +872,7 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat
|
|||
if (target === ConfigurationTarget.MEMORY) {
|
||||
const previous = { data: this._configuration.toData(), workspace: this.workspace };
|
||||
this._configuration.updateValue(key, value, overrides);
|
||||
this.triggerConfigurationChange({ keys: overrides?.overrideIdentifier ? [keyFromOverrideIdentifier(overrides.overrideIdentifier), key] : [key], overrides: overrides?.overrideIdentifier ? [[overrides?.overrideIdentifier, [key]]] : [] }, previous, target);
|
||||
this.triggerConfigurationChange({ keys: overrides?.overrideIdentifiers?.length ? [keyFromOverrideIdentifiers(overrides.overrideIdentifiers), key] : [key], overrides: overrides?.overrideIdentifiers?.length ? overrides.overrideIdentifiers.map(overrideIdentifier => ([overrideIdentifier, [key]])) : [] }, previous, target);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,11 +13,11 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
|||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { IConfigurationService, IConfigurationOverrides, keyFromOverrideIdentifier } from 'vs/platform/configuration/common/configuration';
|
||||
import { IConfigurationService, IConfigurationUpdateOverrides } from 'vs/platform/configuration/common/configuration';
|
||||
import { FOLDER_SETTINGS_PATH, WORKSPACE_STANDALONE_CONFIGURATIONS, TASKS_CONFIGURATION_KEY, LAUNCH_CONFIGURATION_KEY, USER_STANDALONE_CONFIGURATIONS, TASKS_DEFAULT, FOLDER_SCOPES } from 'vs/workbench/services/configuration/common/configuration';
|
||||
import { IFileService, FileOperationError, FileOperationResult } from 'vs/platform/files/common/files';
|
||||
import { IResolvedTextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { OVERRIDE_PROPERTY_PATTERN, IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope, keyFromOverrideIdentifiers, OVERRIDE_PROPERTY_REGEX } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { IOpenSettingsOptions, IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
|
||||
|
@ -113,7 +113,7 @@ export interface IConfigurationEditingOptions {
|
|||
/**
|
||||
* Scope of configuration to be written into.
|
||||
*/
|
||||
scopes?: IConfigurationOverrides;
|
||||
scopes?: IConfigurationUpdateOverrides;
|
||||
}
|
||||
|
||||
export const enum EditableConfigurationTarget {
|
||||
|
@ -243,7 +243,7 @@ export class ConfigurationEditingService {
|
|||
return { insertSpaces, tabSize, eol };
|
||||
}
|
||||
|
||||
private async onError(error: ConfigurationEditingError, operation: IConfigurationEditOperation, scopes: IConfigurationOverrides | undefined): Promise<void> {
|
||||
private async onError(error: ConfigurationEditingError, operation: IConfigurationEditOperation, scopes: IConfigurationUpdateOverrides | undefined): Promise<void> {
|
||||
switch (error.code) {
|
||||
case ConfigurationEditingErrorCode.ERROR_INVALID_CONFIGURATION:
|
||||
this.onInvalidConfigurationError(error, operation);
|
||||
|
@ -279,7 +279,7 @@ export class ConfigurationEditingService {
|
|||
}
|
||||
}
|
||||
|
||||
private onConfigurationFileDirtyError(error: ConfigurationEditingError, operation: IConfigurationEditOperation, scopes: IConfigurationOverrides | undefined): void {
|
||||
private onConfigurationFileDirtyError(error: ConfigurationEditingError, operation: IConfigurationEditOperation, scopes: IConfigurationUpdateOverrides | undefined): void {
|
||||
const openStandAloneConfigurationActionLabel = operation.workspaceStandAloneConfigurationKey === TASKS_CONFIGURATION_KEY ? nls.localize('openTasksConfiguration', "Open Tasks Configuration")
|
||||
: operation.workspaceStandAloneConfigurationKey === LAUNCH_CONFIGURATION_KEY ? nls.localize('openLaunchConfiguration', "Open Launch Configuration")
|
||||
: null;
|
||||
|
@ -475,7 +475,7 @@ export class ConfigurationEditingService {
|
|||
return parseErrors.length > 0;
|
||||
}
|
||||
|
||||
private async validate(target: EditableConfigurationTarget, operation: IConfigurationEditOperation, checkDirty: boolean, overrides: IConfigurationOverrides): Promise<void> {
|
||||
private async validate(target: EditableConfigurationTarget, operation: IConfigurationEditOperation, checkDirty: boolean, overrides: IConfigurationUpdateOverrides): Promise<void> {
|
||||
|
||||
const configurationProperties = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).getConfigurationProperties();
|
||||
const configurationScope = configurationProperties[operation.key]?.scope;
|
||||
|
@ -488,7 +488,7 @@ export class ConfigurationEditingService {
|
|||
*/
|
||||
if (!operation.workspaceStandAloneConfigurationKey) {
|
||||
const validKeys = this.configurationService.keys().default;
|
||||
if (validKeys.indexOf(operation.key) < 0 && !OVERRIDE_PROPERTY_PATTERN.test(operation.key) && operation.value !== undefined) {
|
||||
if (validKeys.indexOf(operation.key) < 0 && !OVERRIDE_PROPERTY_REGEX.test(operation.key) && operation.value !== undefined) {
|
||||
throw this.toConfigurationEditingError(ConfigurationEditingErrorCode.ERROR_UNKNOWN_KEY, target, operation);
|
||||
}
|
||||
}
|
||||
|
@ -506,7 +506,7 @@ export class ConfigurationEditingService {
|
|||
}
|
||||
|
||||
if (target === EditableConfigurationTarget.WORKSPACE) {
|
||||
if (!operation.workspaceStandAloneConfigurationKey && !OVERRIDE_PROPERTY_PATTERN.test(operation.key)) {
|
||||
if (!operation.workspaceStandAloneConfigurationKey && !OVERRIDE_PROPERTY_REGEX.test(operation.key)) {
|
||||
if (configurationScope === ConfigurationScope.APPLICATION) {
|
||||
throw this.toConfigurationEditingError(ConfigurationEditingErrorCode.ERROR_INVALID_WORKSPACE_CONFIGURATION_APPLICATION, target, operation);
|
||||
}
|
||||
|
@ -521,14 +521,14 @@ export class ConfigurationEditingService {
|
|||
throw this.toConfigurationEditingError(ConfigurationEditingErrorCode.ERROR_INVALID_FOLDER_TARGET, target, operation);
|
||||
}
|
||||
|
||||
if (!operation.workspaceStandAloneConfigurationKey && !OVERRIDE_PROPERTY_PATTERN.test(operation.key)) {
|
||||
if (!operation.workspaceStandAloneConfigurationKey && !OVERRIDE_PROPERTY_REGEX.test(operation.key)) {
|
||||
if (configurationScope !== undefined && !FOLDER_SCOPES.includes(configurationScope)) {
|
||||
throw this.toConfigurationEditingError(ConfigurationEditingErrorCode.ERROR_INVALID_FOLDER_CONFIGURATION, target, operation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (overrides.overrideIdentifier) {
|
||||
if (overrides.overrideIdentifiers?.length) {
|
||||
if (configurationScope !== ConfigurationScope.LANGUAGE_OVERRIDABLE) {
|
||||
throw this.toConfigurationEditingError(ConfigurationEditingErrorCode.ERROR_INVALID_RESOURCE_LANGUAGE_CONFIGURATION, target, operation);
|
||||
}
|
||||
|
@ -544,7 +544,7 @@ export class ConfigurationEditingService {
|
|||
|
||||
}
|
||||
|
||||
private getConfigurationEditOperation(target: EditableConfigurationTarget, config: IConfigurationValue, overrides: IConfigurationOverrides): IConfigurationEditOperation {
|
||||
private getConfigurationEditOperation(target: EditableConfigurationTarget, config: IConfigurationValue, overrides: IConfigurationUpdateOverrides): IConfigurationEditOperation {
|
||||
|
||||
// Check for standalone workspace configurations
|
||||
if (config.key) {
|
||||
|
@ -569,7 +569,7 @@ export class ConfigurationEditingService {
|
|||
}
|
||||
|
||||
let key = config.key;
|
||||
let jsonPath = overrides.overrideIdentifier ? [keyFromOverrideIdentifier(overrides.overrideIdentifier), key] : [key];
|
||||
let jsonPath = overrides.overrideIdentifiers?.length ? [keyFromOverrideIdentifiers(overrides.overrideIdentifiers), key] : [key];
|
||||
if (target === EditableConfigurationTarget.USER_LOCAL || target === EditableConfigurationTarget.USER_REMOTE) {
|
||||
return { key, jsonPath, value: config.value, resource: withNullAsUndefined(this.getConfigurationFileResource(target, '', null)), target };
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import * as sinon from 'sinon';
|
|||
import { URI } from 'vs/base/common/uri';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope, keyFromOverrideIdentifiers } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { WorkspaceService } from 'vs/workbench/services/configuration/browser/configurationService';
|
||||
import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { ConfigurationEditingErrorCode } from 'vs/workbench/services/configuration/common/configurationEditingService';
|
||||
|
@ -1012,9 +1012,38 @@ suite('WorkspaceConfigurationService - Folder', () => {
|
|||
.then(() => assert.strictEqual(testObject.getValue('configurationService.folder.testSetting'), 'value'));
|
||||
});
|
||||
|
||||
test('update resource language configuration', () => {
|
||||
return testObject.updateValue('configurationService.folder.languageSetting', 'value', { resource: workspaceService.getWorkspace().folders[0].uri }, ConfigurationTarget.WORKSPACE_FOLDER)
|
||||
.then(() => assert.strictEqual(testObject.getValue('configurationService.folder.languageSetting'), 'value'));
|
||||
test('update language configuration using configuration overrides', async () => {
|
||||
await testObject.updateValue('configurationService.folder.languageSetting', 'abcLangValue', { overrideIdentifier: 'abclang' });
|
||||
assert.strictEqual(testObject.getValue('configurationService.folder.languageSetting', { overrideIdentifier: 'abclang' }), 'abcLangValue');
|
||||
});
|
||||
|
||||
test('update language configuration using configuration update overrides', async () => {
|
||||
await testObject.updateValue('configurationService.folder.languageSetting', 'abcLangValue', { overrideIdentifiers: ['abclang'] });
|
||||
assert.strictEqual(testObject.getValue('configurationService.folder.languageSetting', { overrideIdentifier: 'abclang' }), 'abcLangValue');
|
||||
});
|
||||
|
||||
test('update language configuration for multiple languages', async () => {
|
||||
await testObject.updateValue('configurationService.folder.languageSetting', 'multiLangValue', { overrideIdentifiers: ['deflang', 'xyzlang'] }, ConfigurationTarget.USER);
|
||||
assert.strictEqual(testObject.getValue('configurationService.folder.languageSetting', { overrideIdentifier: 'deflang' }), 'multiLangValue');
|
||||
assert.strictEqual(testObject.getValue('configurationService.folder.languageSetting', { overrideIdentifier: 'xyzlang' }), 'multiLangValue');
|
||||
assert.deepStrictEqual(testObject.getValue(keyFromOverrideIdentifiers(['deflang', 'xyzlang'])), { 'configurationService.folder.languageSetting': 'multiLangValue' });
|
||||
});
|
||||
|
||||
test('update resource language configuration', async () => {
|
||||
await testObject.updateValue('configurationService.folder.languageSetting', 'value', { resource: workspaceService.getWorkspace().folders[0].uri }, ConfigurationTarget.WORKSPACE_FOLDER);
|
||||
assert.strictEqual(testObject.getValue('configurationService.folder.languageSetting'), 'value');
|
||||
});
|
||||
|
||||
test('update resource language configuration for a language using configuration overrides', async () => {
|
||||
assert.strictEqual(testObject.getValue('configurationService.folder.languageSetting', { resource: workspaceService.getWorkspace().folders[0].uri, overrideIdentifier: 'jsonc' }), 'languageValue');
|
||||
await testObject.updateValue('configurationService.folder.languageSetting', 'languageValueUpdated', { resource: workspaceService.getWorkspace().folders[0].uri, overrideIdentifier: 'jsonc' }, ConfigurationTarget.WORKSPACE_FOLDER);
|
||||
assert.strictEqual(testObject.getValue('configurationService.folder.languageSetting', { resource: workspaceService.getWorkspace().folders[0].uri, overrideIdentifier: 'jsonc' }), 'languageValueUpdated');
|
||||
});
|
||||
|
||||
test('update resource language configuration for a language using configuration update overrides', async () => {
|
||||
assert.strictEqual(testObject.getValue('configurationService.folder.languageSetting', { resource: workspaceService.getWorkspace().folders[0].uri, overrideIdentifier: 'jsonc' }), 'languageValue');
|
||||
await testObject.updateValue('configurationService.folder.languageSetting', 'languageValueUpdated', { resource: workspaceService.getWorkspace().folders[0].uri, overrideIdentifiers: ['jsonc'] }, ConfigurationTarget.WORKSPACE_FOLDER);
|
||||
assert.strictEqual(testObject.getValue('configurationService.folder.languageSetting', { resource: workspaceService.getWorkspace().folders[0].uri, overrideIdentifier: 'jsonc' }), 'languageValueUpdated');
|
||||
});
|
||||
|
||||
test('update application setting into workspace configuration in a workspace is not supported', () => {
|
||||
|
@ -1058,12 +1087,6 @@ suite('WorkspaceConfigurationService - Folder', () => {
|
|||
.then(() => assert.ok(target.called));
|
||||
});
|
||||
|
||||
test('resource language configuration', async () => {
|
||||
assert.strictEqual(testObject.getValue('configurationService.folder.languageSetting', { resource: workspaceService.getWorkspace().folders[0].uri, overrideIdentifier: 'jsonc' }), 'languageValue');
|
||||
await testObject.updateValue('configurationService.folder.languageSetting', 'languageValueUpdated', { resource: workspaceService.getWorkspace().folders[0].uri, overrideIdentifier: 'jsonc' }, ConfigurationTarget.WORKSPACE_FOLDER);
|
||||
assert.strictEqual(testObject.getValue('configurationService.folder.languageSetting', { resource: workspaceService.getWorkspace().folders[0].uri, overrideIdentifier: 'jsonc' }), 'languageValueUpdated');
|
||||
});
|
||||
|
||||
test('remove setting from all targets', async () => {
|
||||
const key = 'configurationService.folder.testSetting';
|
||||
await testObject.updateValue(key, 'workspaceValue', ConfigurationTarget.WORKSPACE);
|
||||
|
|
|
@ -19,7 +19,7 @@ import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
|||
import * as nls from 'vs/nls';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { Extensions, getDefaultValue, IConfigurationRegistry, OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { Extensions, getDefaultValue, IConfigurationRegistry, OVERRIDE_PROPERTY_REGEX } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { EditorResolution } from 'vs/platform/editor/common/editor';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { FileOperationError, FileOperationResult } from 'vs/platform/files/common/files';
|
||||
|
@ -541,7 +541,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic
|
|||
return null;
|
||||
}
|
||||
const schema = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurationProperties()[settingKey];
|
||||
const isOverrideProperty = OVERRIDE_PROPERTY_PATTERN.test(settingKey);
|
||||
const isOverrideProperty = OVERRIDE_PROPERTY_REGEX.test(settingKey);
|
||||
if (!schema && !isOverrideProperty) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import { IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/mod
|
|||
import { ITextEditorModel } from 'vs/editor/common/services/resolverService';
|
||||
import * as nls from 'vs/nls';
|
||||
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ConfigurationScope, Extensions, IConfigurationNode, IConfigurationPropertySchema, IConfigurationRegistry, OVERRIDE_PROPERTY_PATTERN, IConfigurationExtensionInfo } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { ConfigurationScope, Extensions, IConfigurationNode, IConfigurationPropertySchema, IConfigurationRegistry, IConfigurationExtensionInfo, OVERRIDE_PROPERTY_REGEX } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { EditorModel } from 'vs/workbench/common/editor/editorModel';
|
||||
|
@ -342,7 +342,7 @@ function parse(model: ITextModel, isSettingsProperty: (currentProperty: string,
|
|||
};
|
||||
if (previousParents.length === settingsPropertyIndex + 1) {
|
||||
settings.push(setting);
|
||||
if (OVERRIDE_PROPERTY_PATTERN.test(name)) {
|
||||
if (OVERRIDE_PROPERTY_REGEX.test(name)) {
|
||||
overrideSetting = setting;
|
||||
}
|
||||
} else {
|
||||
|
@ -618,7 +618,7 @@ export class DefaultSettings extends Disposable {
|
|||
description = '';
|
||||
}
|
||||
const descriptionLines = description.split('\n');
|
||||
const overrides = OVERRIDE_PROPERTY_PATTERN.test(key) ? this.parseOverrideSettings(prop.default) : [];
|
||||
const overrides = OVERRIDE_PROPERTY_REGEX.test(key) ? this.parseOverrideSettings(prop.default) : [];
|
||||
let listItemType: string | undefined;
|
||||
if (prop.type === 'array' && prop.items && !isArray(prop.items) && prop.items.type) {
|
||||
if (prop.items.enum) {
|
||||
|
|
Loading…
Reference in a new issue