提交 1762f5a0 编写于 作者: S Sandeep Somavarapu

enable api to read and write lang configs

上级 4af9286a
......@@ -4237,6 +4237,8 @@ declare module 'vscode' {
WorkspaceFolder = 3
}
export type ConfigurationScope = Uri | { resource: Uri, language?: string };
/**
* Represents the configuration. It is a merged view of
*
......@@ -8683,13 +8685,13 @@ declare module 'vscode' {
* is returned. Dots in the section-identifier are interpreted as child-access,
* like `{ myExt: { setting: { doIt: true }}}` and `getConfiguration('myExt.setting').get('doIt') === true`.
*
* When a resource is provided, configuration scoped to that resource is returned.
* When a scope is provided, configuration confined to that scope is returned.
*
* @param section A dot-separated identifier.
* @param resource A resource for which the configuration is asked for
* @param scope A scope for which the configuration is asked for.
* @return The full configuration or a subset.
*/
export function getConfiguration(section?: string, resource?: Uri | null): WorkspaceConfiguration;
export function getConfiguration(section?: string, scope?: ConfigurationScope | null): WorkspaceConfiguration;
/**
* An event that is emitted when the [configuration](#WorkspaceConfiguration) changed.
......
......@@ -3,14 +3,14 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI, UriComponents } from 'vs/base/common/uri';
import { URI } from 'vs/base/common/uri';
import { IDisposable } from 'vs/base/common/lifecycle';
import { Registry } from 'vs/platform/registry/common/platform';
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope, getScopes } from 'vs/platform/configuration/common/configurationRegistry';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { MainThreadConfigurationShape, MainContext, ExtHostContext, IExtHostContext, IConfigurationInitData } from '../common/extHost.protocol';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ConfigurationTarget, IConfigurationService, IConfigurationOverrides, IConfigurationValue } from 'vs/platform/configuration/common/configuration';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
@extHostNamedCustomer(MainContext.MainThreadConfiguration)
......@@ -45,23 +45,60 @@ export class MainThreadConfiguration implements MainThreadConfigurationShape {
this._configurationListener.dispose();
}
$updateConfigurationOption(target: ConfigurationTarget | null, key: string, value: any, resourceUriComponenets: UriComponents | undefined): Promise<void> {
const resource = resourceUriComponenets ? URI.revive(resourceUriComponenets) : null;
return this.writeConfiguration(target, key, value, resource);
$updateConfigurationOption(target: ConfigurationTarget | null, key: string, value: any, overrides: IConfigurationOverrides | undefined): Promise<void> {
overrides = { resource: overrides?.resource ? URI.revive(overrides.resource) : undefined, overrideIdentifier: overrides?.overrideIdentifier };
return this.writeConfiguration(target, key, value, overrides);
}
$removeConfigurationOption(target: ConfigurationTarget | null, key: string, resourceUriComponenets: UriComponents | undefined): Promise<void> {
const resource = resourceUriComponenets ? URI.revive(resourceUriComponenets) : null;
return this.writeConfiguration(target, key, undefined, resource);
$removeConfigurationOption(target: ConfigurationTarget | null, key: string, overrides: IConfigurationOverrides | undefined): Promise<void> {
overrides = { resource: overrides?.resource ? URI.revive(overrides.resource) : undefined, overrideIdentifier: overrides?.overrideIdentifier };
return this.writeConfiguration(target, key, undefined, overrides);
}
private writeConfiguration(target: ConfigurationTarget | null, key: string, value: any, resource: URI | null): Promise<void> {
target = target !== null && target !== undefined ? target : this.deriveConfigurationTarget(key, resource);
return this.configurationService.updateValue(key, value, { resource }, target, true);
private writeConfiguration(target: ConfigurationTarget | null, key: string, value: any, overrides: IConfigurationOverrides): Promise<void> {
const configurationValue = this.configurationService.inspect(key, overrides);
target = target !== null && target !== undefined ? target : this.deriveConfigurationTarget(key, configurationValue, overrides);
switch (target) {
case ConfigurationTarget.MEMORY:
return this._updateValue(key, value, target, configurationValue.memory?.override, overrides);
case ConfigurationTarget.WORKSPACE_FOLDER:
return this._updateValue(key, value, target, configurationValue.workspaceFolder?.override, overrides);
case ConfigurationTarget.WORKSPACE:
return this._updateValue(key, value, target, configurationValue.workspace?.override, overrides);
case ConfigurationTarget.USER_REMOTE:
return this._updateValue(key, value, target, configurationValue.userRemote?.override, overrides);
default:
return this._updateValue(key, value, target, configurationValue.userLocal?.override, overrides);
}
}
private _updateValue(key: string, value: any, configurationTarget: ConfigurationTarget, overriddenValue: any | undefined, overrides: IConfigurationOverrides): Promise<void> {
if (overrides.overrideIdentifier && overriddenValue !== undefined) {
return this.configurationService.updateValue(key, value, overrides, configurationTarget);
} else {
return this.configurationService.updateValue(key, value, { resource: overrides.resource }, configurationTarget);
}
}
private deriveConfigurationTarget(key: string, resource: URI | null): ConfigurationTarget {
if (resource && this._workspaceContextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
private deriveConfigurationTarget(key: string, configurationValue: IConfigurationValue<any>, overrides: IConfigurationOverrides): ConfigurationTarget {
if (overrides.overrideIdentifier) {
if (configurationValue.memory?.override !== undefined) {
return ConfigurationTarget.MEMORY;
}
if (configurationValue.workspaceFolder?.override !== undefined) {
return ConfigurationTarget.WORKSPACE_FOLDER;
}
if (configurationValue.workspace?.override !== undefined) {
return ConfigurationTarget.WORKSPACE;
}
if (configurationValue.userRemote?.override !== undefined) {
return ConfigurationTarget.USER_REMOTE;
}
if (configurationValue.userLocal?.override !== undefined) {
return ConfigurationTarget.USER_LOCAL;
}
}
if (overrides.resource && this._workspaceContextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
const configurationProperties = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).getConfigurationProperties();
if (configurationProperties[key] && (configurationProperties[key].scope === ConfigurationScope.RESOURCE || configurationProperties[key].scope === ConfigurationScope.RESOURCE_LANGUAGE)) {
return ConfigurationTarget.WORKSPACE_FOLDER;
......
......@@ -664,9 +664,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
onDidChangeConfiguration: (listener: (_: any) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => {
return configProvider.onDidChangeConfiguration(listener, thisArgs, disposables);
},
getConfiguration(section?: string, resource?: vscode.Uri): vscode.WorkspaceConfiguration {
resource = arguments.length === 1 ? undefined : resource;
return configProvider.getConfiguration(section, resource, extension.identifier);
getConfiguration(section?: string, scope?: vscode.ConfigurationScope): vscode.WorkspaceConfiguration {
scope = arguments.length === 1 ? undefined : scope;
return configProvider.getConfiguration(section, scope, extension.identifier);
},
registerTextDocumentContentProvider(scheme: string, provider: vscode.TextDocumentContentProvider) {
return extHostDocumentContentProviders.registerTextDocumentContentProvider(scheme, provider);
......
......@@ -22,7 +22,7 @@ import { IModelChangedEvent } from 'vs/editor/common/model/mirrorTextModel';
import * as modes from 'vs/editor/common/modes';
import { CharacterPair, CommentRule, EnterAction } from 'vs/editor/common/modes/languageConfiguration';
import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
import { ConfigurationTarget, IConfigurationData, IConfigurationChange } from 'vs/platform/configuration/common/configuration';
import { ConfigurationTarget, IConfigurationData, IConfigurationChange, IConfigurationOverrides } from 'vs/platform/configuration/common/configuration';
import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import * as files from 'vs/platform/files/common/files';
......@@ -147,8 +147,8 @@ export interface MainThreadCommentsShape extends IDisposable {
}
export interface MainThreadConfigurationShape extends IDisposable {
$updateConfigurationOption(target: ConfigurationTarget | null, key: string, value: any, resource: UriComponents | undefined): Promise<void>;
$removeConfigurationOption(target: ConfigurationTarget | null, key: string, resource: UriComponents | undefined): Promise<void>;
$updateConfigurationOption(target: ConfigurationTarget | null, key: string, value: any, overrides: IConfigurationOverrides | undefined): Promise<void>;
$removeConfigurationOption(target: ConfigurationTarget | null, key: string, overrides: IConfigurationOverrides | undefined): Promise<void>;
}
export interface MainThreadDiagnosticsShape extends IDisposable {
......
......@@ -10,7 +10,7 @@ import * as vscode from 'vscode';
import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { ExtHostConfigurationShape, MainThreadConfigurationShape, IConfigurationInitData, MainContext } from './extHost.protocol';
import { ConfigurationTarget as ExtHostConfigurationTarget } from './extHostTypes';
import { ConfigurationTarget, IConfigurationChange, IConfigurationData } from 'vs/platform/configuration/common/configuration';
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 { isObject } from 'vs/base/common/types';
......@@ -104,13 +104,14 @@ export class ExtHostConfigProvider {
this._onDidChangeConfiguration.fire(this._toConfigurationChangeEvent(change, previous));
}
getConfiguration(section?: string, resource?: URI, extensionId?: ExtensionIdentifier): vscode.WorkspaceConfiguration {
getConfiguration(section?: string, scope?: vscode.ConfigurationScope, extensionId?: ExtensionIdentifier): vscode.WorkspaceConfiguration {
const overrides: IConfigurationOverrides = scope ? scope instanceof vscode.Uri ? { resource: scope } : { resource: scope.resource, overrideIdentifier: scope.language } : {};
const config = this._toReadonlyValue(section
? lookUp(this._configuration.getValue(undefined, { resource }, this._extHostWorkspace.workspace), section)
: this._configuration.getValue(undefined, { resource }, this._extHostWorkspace.workspace));
? lookUp(this._configuration.getValue(undefined, overrides, this._extHostWorkspace.workspace), section)
: this._configuration.getValue(undefined, overrides, this._extHostWorkspace.workspace));
if (section) {
this._validateConfigurationAccess(section, resource, extensionId);
this._validateConfigurationAccess(section, overrides, extensionId);
}
function parseConfigurationTarget(arg: boolean | ExtHostConfigurationTarget): ConfigurationTarget | null {
......@@ -133,7 +134,7 @@ export class ExtHostConfigProvider {
return typeof lookUp(config, key) !== 'undefined';
},
get: <T>(key: string, defaultValue?: T) => {
this._validateConfigurationAccess(section ? `${section}.${key}` : key, resource, extensionId);
this._validateConfigurationAccess(section ? `${section}.${key}` : key, overrides, extensionId);
let result = lookUp(config, key);
if (typeof result === 'undefined') {
result = defaultValue;
......@@ -193,14 +194,14 @@ export class ExtHostConfigProvider {
key = section ? `${section}.${key}` : key;
const target = parseConfigurationTarget(arg);
if (value !== undefined) {
return this._proxy.$updateConfigurationOption(target, key, value, resource);
return this._proxy.$updateConfigurationOption(target, key, value, overrides);
} else {
return this._proxy.$removeConfigurationOption(target, key, resource);
return this._proxy.$removeConfigurationOption(target, key, overrides);
}
},
inspect: <T>(key: string): ConfigurationInspect<T> | undefined => {
key = section ? `${section}.${key}` : key;
const config = deepClone(this._configuration.inspect<T>(key, { resource }, this._extHostWorkspace.workspace));
const config = deepClone(this._configuration.inspect<T>(key, overrides, this._extHostWorkspace.workspace));
if (config) {
return {
key,
......@@ -237,17 +238,17 @@ export class ExtHostConfigProvider {
return readonlyProxy(result);
}
private _validateConfigurationAccess(key: string, resource: URI | undefined, extensionId?: ExtensionIdentifier): void {
private _validateConfigurationAccess(key: string, overrides?: IConfigurationOverrides, extensionId?: ExtensionIdentifier): void {
const scope = OVERRIDE_PROPERTY_PATTERN.test(key) ? ConfigurationScope.RESOURCE : this._configurationScopes.get(key);
const extensionIdText = extensionId ? `[${extensionId.value}] ` : '';
if (ConfigurationScope.RESOURCE === scope) {
if (resource === undefined) {
if (overrides?.resource) {
this._logService.warn(`${extensionIdText}Accessing a resource scoped configuration without providing a resource is not expected. To get the effective value for '${key}', provide the URI of a resource or 'null' for any resource.`);
}
return;
}
if (ConfigurationScope.WINDOW === scope) {
if (resource) {
if (overrides?.resource) {
this._logService.warn(`${extensionIdText}Accessing a window scoped configuration for a resource is not expected. To associate '${key}' to a resource, define its scope to 'resource' in configuration contributions in 'package.json'.`);
}
return;
......
......@@ -72,7 +72,7 @@ suite('MainThreadConfiguration', function () {
instantiationService.stub(IWorkspaceContextService, <IWorkspaceContextService>{ getWorkbenchState: () => WorkbenchState.FOLDER });
const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy));
testObject.$updateConfigurationOption(null, 'extHostConfiguration.resource', 'value', URI.file('abc'));
testObject.$updateConfigurationOption(null, 'extHostConfiguration.resource', 'value', { resource: URI.file('abc') });
assert.equal(ConfigurationTarget.WORKSPACE, target.args[0][3]);
});
......@@ -99,7 +99,7 @@ suite('MainThreadConfiguration', function () {
instantiationService.stub(IWorkspaceContextService, <IWorkspaceContextService>{ getWorkbenchState: () => WorkbenchState.WORKSPACE });
const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy));
testObject.$updateConfigurationOption(null, 'extHostConfiguration.window', 'value', URI.file('abc'));
testObject.$updateConfigurationOption(null, 'extHostConfiguration.window', 'value', { resource: URI.file('abc') });
assert.equal(ConfigurationTarget.WORKSPACE, target.args[0][3]);
});
......@@ -108,7 +108,7 @@ suite('MainThreadConfiguration', function () {
instantiationService.stub(IWorkspaceContextService, <IWorkspaceContextService>{ getWorkbenchState: () => WorkbenchState.FOLDER });
const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy));
testObject.$updateConfigurationOption(null, 'extHostConfiguration.window', 'value', URI.file('abc'));
testObject.$updateConfigurationOption(null, 'extHostConfiguration.window', 'value', { resource: URI.file('abc') });
assert.equal(ConfigurationTarget.WORKSPACE, target.args[0][3]);
});
......@@ -126,7 +126,7 @@ suite('MainThreadConfiguration', function () {
instantiationService.stub(IWorkspaceContextService, <IWorkspaceContextService>{ getWorkbenchState: () => WorkbenchState.WORKSPACE });
const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy));
testObject.$updateConfigurationOption(null, 'extHostConfiguration.resource', 'value', URI.file('abc'));
testObject.$updateConfigurationOption(null, 'extHostConfiguration.resource', 'value', { resource: URI.file('abc') });
assert.equal(ConfigurationTarget.WORKSPACE_FOLDER, target.args[0][3]);
});
......@@ -135,7 +135,7 @@ suite('MainThreadConfiguration', function () {
instantiationService.stub(IWorkspaceContextService, <IWorkspaceContextService>{ getWorkbenchState: () => WorkbenchState.FOLDER });
const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy));
testObject.$updateConfigurationOption(ConfigurationTarget.USER, 'extHostConfiguration.window', 'value', URI.file('abc'));
testObject.$updateConfigurationOption(ConfigurationTarget.USER, 'extHostConfiguration.window', 'value', { resource: URI.file('abc') });
assert.equal(ConfigurationTarget.USER, target.args[0][3]);
});
......@@ -144,7 +144,7 @@ suite('MainThreadConfiguration', function () {
instantiationService.stub(IWorkspaceContextService, <IWorkspaceContextService>{ getWorkbenchState: () => WorkbenchState.FOLDER });
const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy));
testObject.$updateConfigurationOption(ConfigurationTarget.WORKSPACE, 'extHostConfiguration.window', 'value', URI.file('abc'));
testObject.$updateConfigurationOption(ConfigurationTarget.WORKSPACE, 'extHostConfiguration.window', 'value', { resource: URI.file('abc') });
assert.equal(ConfigurationTarget.WORKSPACE, target.args[0][3]);
});
......@@ -153,7 +153,7 @@ suite('MainThreadConfiguration', function () {
instantiationService.stub(IWorkspaceContextService, <IWorkspaceContextService>{ getWorkbenchState: () => WorkbenchState.FOLDER });
const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy));
testObject.$updateConfigurationOption(ConfigurationTarget.WORKSPACE_FOLDER, 'extHostConfiguration.window', 'value', URI.file('abc'));
testObject.$updateConfigurationOption(ConfigurationTarget.WORKSPACE_FOLDER, 'extHostConfiguration.window', 'value', { resource: URI.file('abc') });
assert.equal(ConfigurationTarget.WORKSPACE_FOLDER, target.args[0][3]);
});
......@@ -171,7 +171,7 @@ suite('MainThreadConfiguration', function () {
instantiationService.stub(IWorkspaceContextService, <IWorkspaceContextService>{ getWorkbenchState: () => WorkbenchState.FOLDER });
const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy));
testObject.$removeConfigurationOption(null, 'extHostConfiguration.resource', URI.file('abc'));
testObject.$removeConfigurationOption(null, 'extHostConfiguration.resource', { resource: URI.file('abc') });
assert.equal(ConfigurationTarget.WORKSPACE, target.args[0][3]);
});
......@@ -198,7 +198,7 @@ suite('MainThreadConfiguration', function () {
instantiationService.stub(IWorkspaceContextService, <IWorkspaceContextService>{ getWorkbenchState: () => WorkbenchState.WORKSPACE });
const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy));
testObject.$removeConfigurationOption(null, 'extHostConfiguration.window', URI.file('abc'));
testObject.$removeConfigurationOption(null, 'extHostConfiguration.window', { resource: URI.file('abc') });
assert.equal(ConfigurationTarget.WORKSPACE, target.args[0][3]);
});
......@@ -207,7 +207,7 @@ suite('MainThreadConfiguration', function () {
instantiationService.stub(IWorkspaceContextService, <IWorkspaceContextService>{ getWorkbenchState: () => WorkbenchState.FOLDER });
const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy));
testObject.$removeConfigurationOption(null, 'extHostConfiguration.window', URI.file('abc'));
testObject.$removeConfigurationOption(null, 'extHostConfiguration.window', { resource: URI.file('abc') });
assert.equal(ConfigurationTarget.WORKSPACE, target.args[0][3]);
});
......@@ -225,7 +225,7 @@ suite('MainThreadConfiguration', function () {
instantiationService.stub(IWorkspaceContextService, <IWorkspaceContextService>{ getWorkbenchState: () => WorkbenchState.WORKSPACE });
const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy));
testObject.$removeConfigurationOption(null, 'extHostConfiguration.resource', URI.file('abc'));
testObject.$removeConfigurationOption(null, 'extHostConfiguration.resource', { resource: URI.file('abc') });
assert.equal(ConfigurationTarget.WORKSPACE_FOLDER, target.args[0][3]);
});
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册