diff --git a/src/vs/platform/configuration/common/configuration.ts b/src/vs/platform/configuration/common/configuration.ts index 807ce9e1ba1e934b4afa76a327f72b82a6dc0853..5685e78cd4172962a0d0343db840123c69483f8f 100644 --- a/src/vs/platform/configuration/common/configuration.ts +++ b/src/vs/platform/configuration/common/configuration.ts @@ -207,6 +207,7 @@ export class Configuration { private _globalConfiguration: ConfigurationModel; private _workspaceConsolidatedConfiguration: ConfigurationModel; + private _legacyWorkspaceConsolidatedConfiguration: ConfigurationModel; protected _foldersConsolidatedConfigurations: StrictResourceMap>; constructor(protected _defaults: ConfigurationModel, protected _user: ConfigurationModel, protected _workspaceConfiguration: ConfigurationModel = new ConfigurationModel(), protected folders: StrictResourceMap> = new StrictResourceMap>(), protected _workspace?: Workspace) { @@ -224,6 +225,7 @@ export class Configuration { protected merge(): void { this._globalConfiguration = new ConfigurationModel().merge(this._defaults).merge(this._user); this._workspaceConsolidatedConfiguration = new ConfigurationModel().merge(this._globalConfiguration).merge(this._workspaceConfiguration); + this._legacyWorkspaceConsolidatedConfiguration = null; this._foldersConsolidatedConfigurations = new StrictResourceMap>(); for (const folder of this.folders.keys()) { this.mergeFolder(folder); @@ -252,6 +254,20 @@ export class Configuration { }; } + lookupLegacy(key: string): IConfigurationValue { + if (!this._legacyWorkspaceConsolidatedConfiguration) { + this._legacyWorkspaceConsolidatedConfiguration = this._workspace ? new ConfigurationModel().merge(this._workspaceConfiguration).merge(this.folders.get(this._workspace.roots[0])) : null; + } + const consolidateConfigurationModel = this.getConsolidateConfigurationModel({}); + return { + default: objects.clone(getConfigurationValue(this._defaults.contents, key)), + user: objects.clone(getConfigurationValue(this._user.contents, key)), + workspace: objects.clone(this._legacyWorkspaceConsolidatedConfiguration ? getConfigurationValue(this._legacyWorkspaceConsolidatedConfiguration.contents, key) : void 0), + folder: void 0, + value: objects.clone(getConfigurationValue(consolidateConfigurationModel.contents, key)) + }; + } + keys(): IConfigurationKeys { return { default: this._defaults.keys, diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 468ce5da5fd5bd47ba0ee887cf334da69393e4e0..e38462095eb81a3397d5aeda9a5d42447eb3acc4 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -430,7 +430,7 @@ export function createApiFactory( return extHostConfiguration.getConfiguration(section); }, getConfiguration2: proposedApiFunction(extension, (section?: string, resource?: vscode.Uri): vscode.WorkspaceConfiguration => { - return extHostConfiguration.getConfiguration(section, resource); + return extHostConfiguration.getConfiguration2(section, resource); }), registerTaskProvider: proposedApiFunction(extension, (type: string, provider: vscode.TaskProvider) => { return extHostTask.registerTaskProvider(extension, provider); diff --git a/src/vs/workbench/api/node/extHostConfiguration.ts b/src/vs/workbench/api/node/extHostConfiguration.ts index 884983954328c220cd8ced10450385a64fb13dd1..b900063a3788428ee3d7180c5279d16f114d91da 100644 --- a/src/vs/workbench/api/node/extHostConfiguration.ts +++ b/src/vs/workbench/api/node/extHostConfiguration.ts @@ -7,7 +7,7 @@ import { mixin } from 'vs/base/common/objects'; import URI from 'vs/base/common/uri'; import Event, { Emitter } from 'vs/base/common/event'; -import { WorkspaceConfiguration } from 'vscode'; +import { WorkspaceConfiguration, WorkspaceConfiguration2 } from 'vscode'; import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; import { ExtHostConfigurationShape, MainThreadConfigurationShape } from './extHost.protocol'; import { IConfigurationData, Configuration } from 'vs/platform/configuration/common/configuration'; @@ -24,6 +24,14 @@ function lookUp(tree: any, key: string) { } } +type ConfigurationInspect = { + key: string; + defaultValue?: T; + globalValue?: T; + workspaceValue?: T; + folderValue?: T; +}; + export class ExtHostConfiguration extends ExtHostConfigurationShape { private readonly _onDidChangeConfiguration = new Emitter(); @@ -47,7 +55,15 @@ export class ExtHostConfiguration extends ExtHostConfigurationShape { this._onDidChangeConfiguration.fire(undefined); } - getConfiguration(section?: string, resource?: URI): WorkspaceConfiguration { + getConfiguration(section?: string): WorkspaceConfiguration { + return this._getConfiguration(section, null, true); + } + + getConfiguration2(section?: string, resource?: URI): WorkspaceConfiguration2 { + return this._getConfiguration(section, resource, false); + } + + private _getConfiguration(section: string, resource: URI, legacy: boolean): WorkspaceConfiguration { const config = section ? lookUp(this._configuration.getValue(null, { resource }), section) @@ -73,17 +89,20 @@ export class ExtHostConfiguration extends ExtHostConfigurationShape { return this._proxy.$removeConfigurationOption(target, key); } }, - inspect: (key: string): { key: string; defaultValue?: T; globalValue?: T; workspaceValue?: T, folderValue?: T } => { + inspect: (key: string): ConfigurationInspect => { key = section ? `${section}.${key}` : key; - const config = this._configuration.values()[key]; + const config = legacy ? this._configuration.lookupLegacy(key) : this._configuration.lookup(key, { resource }); if (config) { - return { + const inspect: ConfigurationInspect = { key, defaultValue: config.default, globalValue: config.user, workspaceValue: config.workspace, - folderValue: config.folder }; + if (!legacy) { + inspect.folderValue = config.folder; + } + return inspect; } return undefined; } diff --git a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts index 4a4fb81723824d89470fa2159162f6f6f0a05d4b..7a70b22c8449a898550dbe97037b7ee789d2310e 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts @@ -84,7 +84,40 @@ suite('ExtHostConfiguration', function () { assert.deepEqual(config.get('nested'), { config1: 42, config2: 'Das Pferd frisst kein Reis.' }); }); - test('inspect', function () { + test('inspect in no workspace context', function () { + const testObject = new ExtHostConfiguration( + new class extends MainThreadConfigurationShape { }, + new ExtHostWorkspace(new TestThreadService(), null), + { + defaults: new ConfigurationModel({ + 'editor': { + 'wordWrap': 'off' + } + }, ['editor.wordWrap']), + user: new ConfigurationModel({ + 'editor': { + 'wordWrap': 'on' + } + }, ['editor.wordWrap']), + workspace: new ConfigurationModel({}, []), + folders: Object.create(null) + } + ); + + let actual = testObject.getConfiguration().inspect('editor.wordWrap'); + assert.equal(actual.defaultValue, 'off'); + assert.equal(actual.globalValue, 'on'); + assert.equal(actual.workspaceValue, undefined); + assert.ok(Object.keys(actual).indexOf('folderValue') === -1); + + actual = testObject.getConfiguration('editor').inspect('wordWrap'); + assert.equal(actual.defaultValue, 'off'); + assert.equal(actual.globalValue, 'on'); + assert.equal(actual.workspaceValue, undefined); + assert.ok(Object.keys(actual).indexOf('folderValue') === -1); + }); + + test('inspect in single root context', function () { const workspaceUri = URI.file('foo'); const folders = Object.create(null); const workspace = new ConfigurationModel({ @@ -116,10 +149,140 @@ suite('ExtHostConfiguration', function () { } ); - const actual = testObject.getConfiguration().inspect('editor.wordWrap'); - assert.equal(actual.defaultValue, 'off'); - assert.equal(actual.globalValue, 'on'); - assert.equal(actual.workspaceValue, 'bounded'); + let actual1 = testObject.getConfiguration().inspect('editor.wordWrap'); + assert.equal(actual1.defaultValue, 'off'); + assert.equal(actual1.globalValue, 'on'); + assert.equal(actual1.workspaceValue, 'bounded'); + assert.ok(Object.keys(actual1).indexOf('folderValue') === -1); + + actual1 = testObject.getConfiguration('editor').inspect('wordWrap'); + assert.equal(actual1.defaultValue, 'off'); + assert.equal(actual1.globalValue, 'on'); + assert.equal(actual1.workspaceValue, 'bounded'); + assert.ok(Object.keys(actual1).indexOf('folderValue') === -1); + + let actual2 = testObject.getConfiguration2(null, workspaceUri).inspect('editor.wordWrap'); + assert.equal(actual2.defaultValue, 'off'); + assert.equal(actual2.globalValue, 'on'); + assert.equal(actual2.workspaceValue, 'bounded'); + assert.equal(actual2.folderValue, 'bounded'); + + actual2 = testObject.getConfiguration2('editor', workspaceUri).inspect('wordWrap'); + assert.equal(actual2.defaultValue, 'off'); + assert.equal(actual2.globalValue, 'on'); + assert.equal(actual2.workspaceValue, 'bounded'); + assert.equal(actual2.folderValue, 'bounded'); + }); + + test('inspect in multi root context', function () { + const workspace = new ConfigurationModel({ + 'editor': { + 'wordWrap': 'bounded' + } + }, ['editor.wordWrap']); + + const firstRoot = URI.file('foo1'); + const secondRoot = URI.file('foo2'); + const thirdRoot = URI.file('foo3'); + const folders = Object.create(null); + folders[firstRoot.toString()] = new ConfigurationModel({ + 'editor': { + 'wordWrap': 'off', + 'lineNumbers': 'relative' + } + }, ['editor.wordWrap']); + folders[secondRoot.toString()] = new ConfigurationModel({ + 'editor': { + 'wordWrap': 'on' + } + }, ['editor.wordWrap']); + folders[thirdRoot.toString()] = new ConfigurationModel({}, []); + + const testObject = new ExtHostConfiguration( + new class extends MainThreadConfigurationShape { }, + new ExtHostWorkspace(new TestThreadService(), { + 'id': 'foo', + 'roots': [firstRoot, secondRoot], + 'name': 'foo' + }), + { + defaults: new ConfigurationModel({ + 'editor': { + 'wordWrap': 'off', + 'lineNumbers': 'on' + } + }, ['editor.wordWrap']), + user: new ConfigurationModel({ + 'editor': { + 'wordWrap': 'on' + } + }, ['editor.wordWrap']), + workspace, + folders + } + ); + + let actual1 = testObject.getConfiguration().inspect('editor.wordWrap'); + assert.equal(actual1.defaultValue, 'off'); + assert.equal(actual1.globalValue, 'on'); + assert.equal(actual1.workspaceValue, 'off'); + assert.ok(Object.keys(actual1).indexOf('folderValue') === -1); + + actual1 = testObject.getConfiguration('editor').inspect('wordWrap'); + assert.equal(actual1.defaultValue, 'off'); + assert.equal(actual1.globalValue, 'on'); + assert.equal(actual1.workspaceValue, 'off'); + assert.ok(Object.keys(actual1).indexOf('folderValue') === -1); + + actual1 = testObject.getConfiguration('editor').inspect('lineNumbers'); + assert.equal(actual1.defaultValue, 'on'); + assert.equal(actual1.globalValue, undefined); + assert.equal(actual1.workspaceValue, 'relative'); + assert.ok(Object.keys(actual1).indexOf('folderValue') === -1); + + let actual2 = testObject.getConfiguration2(null, firstRoot).inspect('editor.wordWrap'); + assert.equal(actual2.defaultValue, 'off'); + assert.equal(actual2.globalValue, 'on'); + assert.equal(actual2.workspaceValue, 'bounded'); + assert.equal(actual2.folderValue, 'off'); + + actual2 = testObject.getConfiguration2('editor', firstRoot).inspect('wordWrap'); + assert.equal(actual2.defaultValue, 'off'); + assert.equal(actual2.globalValue, 'on'); + assert.equal(actual2.workspaceValue, 'bounded'); + assert.equal(actual2.folderValue, 'off'); + + actual2 = testObject.getConfiguration2('editor', firstRoot).inspect('lineNumbers'); + assert.equal(actual2.defaultValue, 'on'); + assert.equal(actual2.globalValue, undefined); + assert.equal(actual2.workspaceValue, undefined); + assert.equal(actual2.folderValue, 'relative'); + + actual2 = testObject.getConfiguration2(null, secondRoot).inspect('editor.wordWrap'); + assert.equal(actual2.defaultValue, 'off'); + assert.equal(actual2.globalValue, 'on'); + assert.equal(actual2.workspaceValue, 'bounded'); + assert.equal(actual2.folderValue, 'on'); + + actual2 = testObject.getConfiguration2('editor', secondRoot).inspect('wordWrap'); + assert.equal(actual2.defaultValue, 'off'); + assert.equal(actual2.globalValue, 'on'); + assert.equal(actual2.workspaceValue, 'bounded'); + assert.equal(actual2.folderValue, 'on'); + + actual2 = testObject.getConfiguration2(null, thirdRoot).inspect('editor.wordWrap'); + assert.equal(actual2.defaultValue, 'off'); + assert.equal(actual2.globalValue, 'on'); + assert.equal(actual2.workspaceValue, 'bounded'); + assert.ok(Object.keys(actual2).indexOf('folderValue') !== -1); + assert.equal(actual2.folderValue, undefined); + + actual2 = testObject.getConfiguration2('editor', thirdRoot).inspect('wordWrap'); + assert.equal(actual2.defaultValue, 'off'); + assert.equal(actual2.globalValue, 'on'); + assert.equal(actual2.workspaceValue, 'bounded'); + assert.ok(Object.keys(actual2).indexOf('folderValue') !== -1); + assert.equal(actual2.folderValue, undefined); }); test('getConfiguration vs get', function () {