From b68f3b2f38414576627e8e518aa3b0de23c9432c Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 9 Feb 2017 00:22:39 +0100 Subject: [PATCH] #19733 Default configurations - Define a new extension point `configurationDefaults` for contributing default language specific editor settings --- extensions/vscode-api-tests/package.json | 6 ++ .../src/configuration.test.ts | 20 +++++ .../common/configurationRegistry.ts | 85 +++++++++++-------- .../configuration/test/common/model.test.ts | 21 +---- 4 files changed, 76 insertions(+), 56 deletions(-) create mode 100644 extensions/vscode-api-tests/src/configuration.test.ts diff --git a/extensions/vscode-api-tests/package.json b/extensions/vscode-api-tests/package.json index 357ed7a26977f..93ac38acad8aa 100644 --- a/extensions/vscode-api-tests/package.json +++ b/extensions/vscode-api-tests/package.json @@ -32,6 +32,12 @@ "default": "get-prop" } } + }, + "configurationDefaults": { + "[abcLang]": { + "editor.lineNumbers": "off", + "editor.tabSize": 2 + } } }, "scripts": { diff --git a/extensions/vscode-api-tests/src/configuration.test.ts b/extensions/vscode-api-tests/src/configuration.test.ts new file mode 100644 index 0000000000000..8b063ae4c7819 --- /dev/null +++ b/extensions/vscode-api-tests/src/configuration.test.ts @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import * as vscode from 'vscode'; + +suite('Configuration tests', () => { + + test('Default configurations', function () { + const defaultLanguageSettings = vscode.workspace.getConfiguration().get('[abcLang]'); + + assert.deepEqual(defaultLanguageSettings, { + 'editor.lineNumbers': 'off', + 'editor.tabSize': 2 + }); + }); + +}); \ No newline at end of file diff --git a/src/vs/platform/configuration/common/configurationRegistry.ts b/src/vs/platform/configuration/common/configurationRegistry.ts index e774aa7fb0c0a..7b7847f97d65b 100644 --- a/src/vs/platform/configuration/common/configurationRegistry.ts +++ b/src/vs/platform/configuration/common/configurationRegistry.ts @@ -67,8 +67,10 @@ export interface IConfigurationNode { overridable?: boolean; } -export interface IConfigurationExtension extends IConfigurationNode { - defaults?: any; +export interface IDefaultConfigurationExtension { + id: string; + name: string; + defaults: { [key: string]: {} }; } const schemaId = 'vscode://schemas/settings'; @@ -106,7 +108,6 @@ class ConfigurationRegistry implements IConfigurationRegistry { public registerConfigurations(configurations: IConfigurationNode[]): void { configurations.forEach(configuration => { - this.registerDefaultOverrides(configuration); /// fills in default overrides this.registerProperties(configuration); // fills in defaults this.configurationContributors.push(configuration); this.registerJSONConfiguration(configuration); @@ -121,25 +122,26 @@ class ConfigurationRegistry implements IConfigurationRegistry { this.updateOverridePropertyPatternKey(); } - private registerDefaultOverrides(configurationNode: IConfigurationExtension): void { - if (!configurationNode.defaults) { - return; - } - - for (const key in configurationNode.defaults) { - const defaultValue = configurationNode.defaults[key]; - if (OVERRIDE_PROPERTY_PATTERN.test(key) && typeof defaultValue === 'object') { - if (!configurationNode.properties) { - configurationNode.properties = {}; + public registerDefaultConfigurations(defaultConnfigurations: IDefaultConfigurationExtension[]): void { + const configurationNode: IConfigurationNode = { + id: 'defaultOverrides', + title: nls.localize('defaultConfigurations.title', "Default Configuration Overrides"), + properties: {} + }; + for (const defaultConfiguration of defaultConnfigurations) { + for (const key in defaultConfiguration.defaults) { + const defaultValue = defaultConfiguration.defaults[key]; + if (OVERRIDE_PROPERTY_PATTERN.test(key) && typeof defaultValue === 'object') { + configurationNode.properties[key] = { + type: 'object', + default: defaultValue, + description: nls.localize('overrideSettings.description', "Configure editor settings to be overridden for {0} language.", key), + $ref: editorConfigurationSchemaId + }; } - configurationNode.properties[key] = { - type: 'object', - default: defaultValue, - description: nls.localize('overrideSettings.description', "Configure editor settings to be overridden for {0} language.", key), - $ref: editorConfigurationSchemaId - }; } } + this.registerConfigurations([configurationNode]); } private registerProperties(configuration: IConfigurationNode, overridable: boolean = false) { @@ -291,26 +293,15 @@ const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint { - const configurations: IConfigurationExtension[] = []; + const configurations: IConfigurationNode[] = []; for (let i = 0; i < extensions.length; i++) { - const configuration = extensions[i].value; + const configuration = extensions[i].value; const collector = extensions[i].collector; if (configuration.type && configuration.type !== 'object') { @@ -328,15 +319,35 @@ configurationExtPoint.setHandler(extensions => { return; } - if (configuration.defaults && typeof configuration.defaults !== 'object') { - collector.error(nls.localize('invalid.defaults', "'configuration.defaults' must be an object")); - return; - } - const clonedConfiguration = objects.clone(configuration); clonedConfiguration.id = extensions[i].description.id; configurations.push(clonedConfiguration); } configurationRegistry.registerConfigurations(configurations); +}); + +const defaultConfigurationExtPoint = ExtensionsRegistry.registerExtensionPoint('configurationDefaults', [], { + description: nls.localize('vscode.extension.contributes.defaultConfiguration', 'Contributes default editor configuration settings by language.'), + type: 'object', + defaultSnippets: [{ body: {} }], + patternProperties: { + '\\[.*\\]$': { + type: 'object', + default: {}, + $ref: editorConfigurationSchemaId, + } + } +}); + +defaultConfigurationExtPoint.setHandler(extensions => { + const defaultConfigurations: IDefaultConfigurationExtension[] = extensions.map(extension => { + const id = extension.description.id; + const name = extension.description.name; + const defaults = objects.clone(extension.value); + return { + id, name, defaults + }; + }); + configurationRegistry.registerDefaultConfigurations(defaultConfigurations); }); \ No newline at end of file diff --git a/src/vs/platform/configuration/test/common/model.test.ts b/src/vs/platform/configuration/test/common/model.test.ts index 799cae7afbba5..23d3bbbce82a4 100644 --- a/src/vs/platform/configuration/test/common/model.test.ts +++ b/src/vs/platform/configuration/test/common/model.test.ts @@ -6,22 +6,17 @@ import * as assert from 'assert'; import * as model from 'vs/platform/configuration/common/model'; -import { Extensions, IConfigurationRegistry, IConfigurationExtension } from 'vs/platform/configuration/common/configurationRegistry'; +import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; import { Registry } from 'vs/platform/platform'; suite('ConfigurationService - Model', () => { suiteSetup(() => { - Registry.as(Extensions.Configuration).registerConfiguration({ + Registry.as(Extensions.Configuration).registerConfiguration({ 'id': 'a', 'order': 1, 'title': 'a', 'type': 'object', - 'defaults': { - '[b]': { - 'a': false - } - }, 'properties': { 'a': { 'description': 'a', @@ -131,16 +126,4 @@ suite('ConfigurationService - Model', () => { assert.deepEqual(testObject.keys, []); }); - test('Test default settings', () => { - const testObject = new model.DefaultConfigModel(); - - assert.equal(testObject.getContentsFor('a'), true); - assert.deepEqual(testObject.getContentsFor('[b]'), { 'a': false }); - assert.ok(testObject.keys.indexOf('a') !== -1); - assert.ok(testObject.keys.indexOf('[b]') !== -1); - assert.deepEqual(testObject.overrides, [{ - identifiers: ['b'], - contents: { 'a': false } - }]); - }); }); \ No newline at end of file