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

introduce a config model on the workbench side

上级 e3462718
......@@ -3,9 +3,9 @@
* 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 Event from 'vs/base/common/event';
import {TPromise} from 'vs/base/common/winjs.base';
export const IConfigurationService = createDecorator<IConfigurationService>('configurationService');
......@@ -34,6 +34,9 @@ export interface IConfigurationServiceEvent {
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 {
function accessSetting(config: any, path: string[]): any {
let current = config;
......
......@@ -6,11 +6,11 @@
import nls = require('vs/nls');
import Event, {Emitter} from 'vs/base/common/event';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import platform = require('vs/platform/platform');
import {IJSONSchema} from 'vs/base/common/jsonSchema';
import {Registry} from 'vs/platform/platform';
import objects = require('vs/base/common/objects');
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 = {
Configuration: 'base.contributions.configuration'
......@@ -48,7 +48,7 @@ export interface IConfigurationNode {
}
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 {
private configurationContributors: IConfigurationNode[];
......@@ -86,7 +86,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
}
const configurationRegistry = new ConfigurationRegistry();
platform.Registry.add(Extensions.Configuration, configurationRegistry);
Registry.add(Extensions.Configuration, configurationRegistry);
const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint<IConfigurationNode>('configuration', {
description: nls.localize('vscode.extension.contributes.configuration', 'Contributes configuration settings.'),
......
......@@ -4,21 +4,11 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import objects = require('vs/base/common/objects');
import platform = require('vs/platform/platform');
import {Registry} from 'vs/platform/platform';
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 const CONFIG_DEFAULT_NAME = 'settings';
export interface IConfigFile {
contents: any;
parseError?: any;
}
function setNode(root: any, key: string, value: any): void {
export function setNode(root: any, key: string, value: any): void {
const segments = key.split('.');
const last = segments.pop();
......@@ -36,92 +26,14 @@ function setNode(root: any, key: string, value: any): void {
}
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
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
};
curr[last] = value;
}
// defaults...
function processDefaultValues(withConfig: (config: configurationRegistry.IConfigurationNode, isTop?: boolean) => boolean): void {
const configurations = (<configurationRegistry.IConfigurationRegistry>platform.Registry.as(configurationRegistry.Extensions.Configuration)).getConfigurations();
function processDefaultValues(withConfig: (config: IConfigurationNode, isTop?: boolean) => boolean): void {
const configurations = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurations();
const visit = (config: configurationRegistry.IConfigurationNode, level: number) => {
const visit = (config: IConfigurationNode, level: number) => {
const handled = withConfig(config, level === 0);
if (Array.isArray(config.allOf)) {
......@@ -151,11 +63,10 @@ function processDefaultValues(withConfig: (config: configurationRegistry.IConfig
});
}
export function getDefaultValues(): any {
const ret: any = Object.create(null);
const handleConfig = (config: configurationRegistry.IConfigurationNode, isTop: boolean): boolean => {
const handleConfig = (config: IConfigurationNode, isTop: boolean): boolean => {
if (config.properties) {
Object.keys(config.properties).forEach((key) => {
const prop = config.properties[key];
......@@ -177,13 +88,12 @@ export function getDefaultValues(): any {
return ret;
}
export function getDefaultValuesContent(indent: string): string {
let lastEntry = -1;
const result: string[] = [];
result.push('{');
const handleConfig = (config: configurationRegistry.IConfigurationNode, isTop: boolean): boolean => {
const handleConfig = (config: IConfigurationNode, isTop: boolean): boolean => {
let handled = false;
if (config.title) {
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';
import {applyEdits} from 'vs/base/common/jsonFormatter';
import {setProperty} from 'vs/base/common/jsonEdit';
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 {IWorkbenchConfigurationService} from 'vs/workbench/services/configuration/common/configuration';
import {EventType as FileEventType, FileChangeType, FileChangesEvent} from 'vs/platform/files/common/files';
......
......@@ -5,7 +5,7 @@
'use strict';
import assert = require('assert');
import model = require('vs/platform/configuration/common/model');
import model = require('vs/workbench/services/configuration/common/model');
suite('ConfigurationService - Model', () => {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册