提交 5f144928 编写于 作者: B Benjamin Pasero

introduce a config model on the workbench side

上级 e3462718
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import {TPromise} from 'vs/base/common/winjs.base';
import {createDecorator} from 'vs/platform/instantiation/common/instantiation'; import {createDecorator} from 'vs/platform/instantiation/common/instantiation';
import Event from 'vs/base/common/event'; import Event from 'vs/base/common/event';
import {TPromise} from 'vs/base/common/winjs.base';
export const IConfigurationService = createDecorator<IConfigurationService>('configurationService'); export const IConfigurationService = createDecorator<IConfigurationService>('configurationService');
...@@ -34,6 +34,9 @@ export interface IConfigurationServiceEvent { ...@@ -34,6 +34,9 @@ export interface IConfigurationServiceEvent {
config: any; config: any;
} }
/**
* A helper function to get the configuration value with a specific settings path (e.g. config.some.setting)
*/
export function getConfigurationValue<T>(config: any, settingPath: string, defaultValue?: T): T { export function getConfigurationValue<T>(config: any, settingPath: string, defaultValue?: T): T {
function accessSetting(config: any, path: string[]): any { function accessSetting(config: any, path: string[]): any {
let current = config; let current = config;
......
...@@ -6,11 +6,11 @@ ...@@ -6,11 +6,11 @@
import nls = require('vs/nls'); import nls = require('vs/nls');
import Event, {Emitter} from 'vs/base/common/event'; import Event, {Emitter} from 'vs/base/common/event';
import { IJSONSchema } from 'vs/base/common/jsonSchema'; import {IJSONSchema} from 'vs/base/common/jsonSchema';
import platform = require('vs/platform/platform'); import {Registry} from 'vs/platform/platform';
import objects = require('vs/base/common/objects'); import objects = require('vs/base/common/objects');
import {ExtensionsRegistry} from 'vs/platform/extensions/common/extensionsRegistry'; import {ExtensionsRegistry} from 'vs/platform/extensions/common/extensionsRegistry';
import JSONContributionRegistry = require('vs/platform/jsonschemas/common/jsonContributionRegistry'); import {IJSONContributionRegistry, Extensions as JSONExtensions} from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
export const Extensions = { export const Extensions = {
Configuration: 'base.contributions.configuration' Configuration: 'base.contributions.configuration'
...@@ -48,7 +48,7 @@ export interface IConfigurationNode { ...@@ -48,7 +48,7 @@ export interface IConfigurationNode {
} }
const schemaId = 'vscode://schemas/settings'; const schemaId = 'vscode://schemas/settings';
const contributionRegistry = <JSONContributionRegistry.IJSONContributionRegistry>platform.Registry.as(JSONContributionRegistry.Extensions.JSONContribution); const contributionRegistry = Registry.as<IJSONContributionRegistry>(JSONExtensions.JSONContribution);
class ConfigurationRegistry implements IConfigurationRegistry { class ConfigurationRegistry implements IConfigurationRegistry {
private configurationContributors: IConfigurationNode[]; private configurationContributors: IConfigurationNode[];
...@@ -86,7 +86,7 @@ class ConfigurationRegistry implements IConfigurationRegistry { ...@@ -86,7 +86,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
} }
const configurationRegistry = new ConfigurationRegistry(); const configurationRegistry = new ConfigurationRegistry();
platform.Registry.add(Extensions.Configuration, configurationRegistry); Registry.add(Extensions.Configuration, configurationRegistry);
const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint<IConfigurationNode>('configuration', { const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint<IConfigurationNode>('configuration', {
description: nls.localize('vscode.extension.contributes.configuration', 'Contributes configuration settings.'), description: nls.localize('vscode.extension.contributes.configuration', 'Contributes configuration settings.'),
......
...@@ -4,21 +4,11 @@ ...@@ -4,21 +4,11 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
'use strict'; 'use strict';
import objects = require('vs/base/common/objects'); import {Registry} from 'vs/platform/platform';
import platform = require('vs/platform/platform');
import types = require('vs/base/common/types'); import types = require('vs/base/common/types');
import json = require('vs/base/common/json'); import {IConfigurationNode, IConfigurationRegistry, Extensions} from 'vs/platform/configuration/common/configurationRegistry';
import configurationRegistry = require('./configurationRegistry'); export function setNode(root: any, key: string, value: any): void {
export const CONFIG_DEFAULT_NAME = 'settings';
export interface IConfigFile {
contents: any;
parseError?: any;
}
function setNode(root: any, key: string, value: any): void {
const segments = key.split('.'); const segments = key.split('.');
const last = segments.pop(); const last = segments.pop();
...@@ -36,92 +26,14 @@ function setNode(root: any, key: string, value: any): void { ...@@ -36,92 +26,14 @@ function setNode(root: any, key: string, value: any): void {
} }
curr = obj; curr = obj;
}); });
curr[last] = value;
}
export function newConfigFile(value: string): IConfigFile {
try {
const root: any = Object.create(null);
const contents = json.parse(value) || {};
for (let key in contents) {
setNode(root, key, contents[key]);
}
return {
contents: root
};
} catch (e) {
return {
contents: {},
parseError: e
};
}
}
export function merge(base: any, add: any, overwrite: boolean): void {
Object.keys(add).forEach((key) => {
if (key in base) {
if (types.isObject(base[key]) && types.isObject(add[key])) {
merge(base[key], add[key], overwrite);
} else if (overwrite) {
base[key] = add[key];
}
} else {
base[key] = add[key];
}
});
}
export function consolidate(configMap: { [key: string]: IConfigFile; }): { contents: any; parseErrors: string[]; } {
const finalConfig: any = Object.create(null);
const parseErrors: string[] = [];
const regexp = /\/(team\.)?([^\.]*)*\.json/;
// For each config file in .vscode folder curr[last] = value;
Object.keys(configMap).forEach((configFileName) => {
const config = objects.clone(configMap[configFileName]);
const matches = regexp.exec(configFileName);
if (!matches || !config) {
return;
}
// If a file is team.foo.json, it indicates team settings, strip this away
const isTeamSetting = !!matches[1];
// Extract the config key from the file name (except for settings.json which is the default)
let configElement: any = finalConfig;
if (matches && matches[2] && matches[2] !== CONFIG_DEFAULT_NAME) {
// Use the name of the file as top level config section for all settings inside
const configSection = matches[2];
let element = configElement[configSection];
if (!element) {
element = Object.create(null);
configElement[configSection] = element;
}
configElement = element;
}
merge(configElement, config.contents, !isTeamSetting /* user settings overrule team settings */);
if (config.parseError) {
parseErrors.push(configFileName);
}
});
return {
contents: finalConfig,
parseErrors: parseErrors
};
} }
// defaults... function processDefaultValues(withConfig: (config: IConfigurationNode, isTop?: boolean) => boolean): void {
const configurations = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurations();
function processDefaultValues(withConfig: (config: configurationRegistry.IConfigurationNode, isTop?: boolean) => boolean): void {
const configurations = (<configurationRegistry.IConfigurationRegistry>platform.Registry.as(configurationRegistry.Extensions.Configuration)).getConfigurations();
const visit = (config: configurationRegistry.IConfigurationNode, level: number) => { const visit = (config: IConfigurationNode, level: number) => {
const handled = withConfig(config, level === 0); const handled = withConfig(config, level === 0);
if (Array.isArray(config.allOf)) { if (Array.isArray(config.allOf)) {
...@@ -151,11 +63,10 @@ function processDefaultValues(withConfig: (config: configurationRegistry.IConfig ...@@ -151,11 +63,10 @@ function processDefaultValues(withConfig: (config: configurationRegistry.IConfig
}); });
} }
export function getDefaultValues(): any { export function getDefaultValues(): any {
const ret: any = Object.create(null); const ret: any = Object.create(null);
const handleConfig = (config: configurationRegistry.IConfigurationNode, isTop: boolean): boolean => { const handleConfig = (config: IConfigurationNode, isTop: boolean): boolean => {
if (config.properties) { if (config.properties) {
Object.keys(config.properties).forEach((key) => { Object.keys(config.properties).forEach((key) => {
const prop = config.properties[key]; const prop = config.properties[key];
...@@ -177,13 +88,12 @@ export function getDefaultValues(): any { ...@@ -177,13 +88,12 @@ export function getDefaultValues(): any {
return ret; return ret;
} }
export function getDefaultValuesContent(indent: string): string { export function getDefaultValuesContent(indent: string): string {
let lastEntry = -1; let lastEntry = -1;
const result: string[] = []; const result: string[] = [];
result.push('{'); result.push('{');
const handleConfig = (config: configurationRegistry.IConfigurationNode, isTop: boolean): boolean => { const handleConfig = (config: IConfigurationNode, isTop: boolean): boolean => {
let handled = false; let handled = false;
if (config.title) { if (config.title) {
handled = true; handled = true;
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import objects = require('vs/base/common/objects');
import types = require('vs/base/common/types');
import json = require('vs/base/common/json');
import model = require('vs/platform/configuration/common/model');
export const CONFIG_DEFAULT_NAME = 'settings';
export interface IConfigFile {
contents: any;
parseError?: any;
}
export function newConfigFile(value: string): IConfigFile {
try {
const root: any = Object.create(null);
const contents = json.parse(value) || {};
for (let key in contents) {
model.setNode(root, key, contents[key]);
}
return {
contents: root
};
} catch (e) {
return {
contents: {},
parseError: e
};
}
}
export function merge(base: any, add: any, overwrite: boolean): void {
Object.keys(add).forEach((key) => {
if (key in base) {
if (types.isObject(base[key]) && types.isObject(add[key])) {
merge(base[key], add[key], overwrite);
} else if (overwrite) {
base[key] = add[key];
}
} else {
base[key] = add[key];
}
});
}
export function consolidate(configMap: { [key: string]: IConfigFile; }): { contents: any; parseErrors: string[]; } {
const finalConfig: any = Object.create(null);
const parseErrors: string[] = [];
const regexp = /\/(team\.)?([^\.]*)*\.json/;
// For each config file in .vscode folder
Object.keys(configMap).forEach((configFileName) => {
const config = objects.clone(configMap[configFileName]);
const matches = regexp.exec(configFileName);
if (!matches || !config) {
return;
}
// If a file is team.foo.json, it indicates team settings, strip this away
const isTeamSetting = !!matches[1];
// Extract the config key from the file name (except for settings.json which is the default)
let configElement: any = finalConfig;
if (matches && matches[2] && matches[2] !== CONFIG_DEFAULT_NAME) {
// Use the name of the file as top level config section for all settings inside
const configSection = matches[2];
let element = configElement[configSection];
if (!element) {
element = Object.create(null);
configElement[configSection] = element;
}
configElement = element;
}
merge(configElement, config.contents, !isTeamSetting /* user settings overrule team settings */);
if (config.parseError) {
parseErrors.push(configFileName);
}
});
return {
contents: finalConfig,
parseErrors: parseErrors
};
}
\ No newline at end of file
...@@ -25,7 +25,8 @@ import {JSONPath} from 'vs/base/common/json'; ...@@ -25,7 +25,8 @@ import {JSONPath} from 'vs/base/common/json';
import {applyEdits} from 'vs/base/common/jsonFormatter'; import {applyEdits} from 'vs/base/common/jsonFormatter';
import {setProperty} from 'vs/base/common/jsonEdit'; import {setProperty} from 'vs/base/common/jsonEdit';
import errors = require('vs/base/common/errors'); import errors = require('vs/base/common/errors');
import {IConfigFile, consolidate, CONFIG_DEFAULT_NAME, newConfigFile, getDefaultValues} from 'vs/platform/configuration/common/model'; import {getDefaultValues} from 'vs/platform/configuration/common/model';
import {IConfigFile, consolidate, CONFIG_DEFAULT_NAME, newConfigFile} from 'vs/workbench/services/configuration/common/model';
import {IConfigurationServiceEvent} from 'vs/platform/configuration/common/configuration'; import {IConfigurationServiceEvent} from 'vs/platform/configuration/common/configuration';
import {IWorkbenchConfigurationService} from 'vs/workbench/services/configuration/common/configuration'; import {IWorkbenchConfigurationService} from 'vs/workbench/services/configuration/common/configuration';
import {EventType as FileEventType, FileChangeType, FileChangesEvent} from 'vs/platform/files/common/files'; import {EventType as FileEventType, FileChangeType, FileChangesEvent} from 'vs/platform/files/common/files';
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
'use strict'; 'use strict';
import assert = require('assert'); import assert = require('assert');
import model = require('vs/platform/configuration/common/model'); import model = require('vs/workbench/services/configuration/common/model');
suite('ConfigurationService - Model', () => { suite('ConfigurationService - Model', () => {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册