diff --git a/src/vs/platform/configuration/common/configuration.ts b/src/vs/platform/configuration/common/configuration.ts index 5f5145c0ed3..41093f27f8a 100644 --- a/src/vs/platform/configuration/common/configuration.ts +++ b/src/vs/platform/configuration/common/configuration.ts @@ -43,6 +43,9 @@ export interface IConfigurationChangeEvent { // Following data is used for telemetry source: ConfigurationTarget; sourceConfig: any; + + // Following data is used for Extension host configuration event + toJSON(): IConfigurationChangeEventData; } export interface IConfigurationService { @@ -103,6 +106,11 @@ export interface IConfigurationData { folders: { [folder: string]: IConfiguraionModel }; } +export interface IConfigurationChangeEventData { + changedConfiguration: IConfiguraionModel; + changedConfigurationByResource: { [folder: string]: IConfiguraionModel }; +} + export function compare(from: IConfiguraionModel, to: IConfiguraionModel): { added: string[], removed: string[], updated: string[] } { const added = to.keys.filter(key => from.keys.indexOf(key) === -1); const removed = from.keys.filter(key => to.keys.indexOf(key) === -1); diff --git a/src/vs/platform/configuration/common/configurationModels.ts b/src/vs/platform/configuration/common/configurationModels.ts index 7bfc0852a5e..c58669e9dec 100644 --- a/src/vs/platform/configuration/common/configurationModels.ts +++ b/src/vs/platform/configuration/common/configurationModels.ts @@ -11,7 +11,7 @@ import * as objects from 'vs/base/common/objects'; import URI from 'vs/base/common/uri'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions, OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/configuration/common/configurationRegistry'; -import { IOverrides, overrideIdentifierFromKey, addToValueTree, toValuesTree, IConfiguraionModel, merge, getConfigurationValue, IConfigurationOverrides, IConfigurationData, getDefaultValues, getConfigurationKeys, IConfigurationChangeEvent, ConfigurationTarget, removeFromValueTree } from 'vs/platform/configuration/common/configuration'; +import { IOverrides, overrideIdentifierFromKey, addToValueTree, toValuesTree, IConfiguraionModel, merge, getConfigurationValue, IConfigurationOverrides, IConfigurationData, getDefaultValues, getConfigurationKeys, IConfigurationChangeEvent, ConfigurationTarget, removeFromValueTree, IConfigurationChangeEventData } from 'vs/platform/configuration/common/configuration'; import { Workspace } from 'vs/platform/workspace/common/workspace'; export class ConfigurationModel implements IConfiguraionModel { @@ -481,29 +481,46 @@ export class AbstractConfigurationChangeEvent { export class AllKeysConfigurationChangeEvent extends AbstractConfigurationChangeEvent implements IConfigurationChangeEvent { - private changedConfiguration: ConfigurationModel = null; + private _changedConfiguration: ConfigurationModel = null; constructor(readonly affectedKeys: string[], readonly source: ConfigurationTarget, readonly sourceConfig: any) { super(); } - affectsConfiguration(config: string, resource?: URI): boolean { - if (!this.changedConfiguration) { - this.changedConfiguration = new ConfigurationModel(); - this.updateKeys(this.changedConfiguration, this.affectedKeys); + get changedConfiguration(): ConfigurationModel { + if (!this._changedConfiguration) { + this._changedConfiguration = new ConfigurationModel(); + this.updateKeys(this._changedConfiguration, this.affectedKeys); } + return this._changedConfiguration; + } + + affectsConfiguration(config: string, resource?: URI): boolean { return this.doesConfigurationContains(this.changedConfiguration, config); } + toJSON(): IConfigurationChangeEventData { + return { + changedConfiguration: { + contents: this.changedConfiguration.contents, + overrides: this.changedConfiguration.overrides, + keys: this.changedConfiguration.keys + }, + changedConfigurationByResource: Object.create({}) + }; + } } export class ConfigurationChangeEvent extends AbstractConfigurationChangeEvent implements IConfigurationChangeEvent { - private changedConfiguration: ConfigurationModel = new ConfigurationModel(); - private changedConfigurationByResource: StrictResourceMap = new StrictResourceMap(); - private resources: URI[] = []; - private _source: ConfigurationTarget; private _sourceConfig: any; + constructor( + private changedConfiguration: ConfigurationModel = new ConfigurationModel(), + private resources: URI[] = [], + private changedConfigurationByResource: StrictResourceMap = new StrictResourceMap()) { + super(); + } + change(event: ConfigurationChangeEvent): ConfigurationChangeEvent change(keys: string[], resource?: URI): ConfigurationChangeEvent change(arg1: any, arg2?: any): ConfigurationChangeEvent { @@ -574,4 +591,19 @@ export class ConfigurationChangeEvent extends AbstractConfigurationChangeEvent i } return changedConfigurationByResource; } + + toJSON(): IConfigurationChangeEventData { + return { + changedConfiguration: { + contents: this.changedConfiguration.contents, + overrides: this.changedConfiguration.overrides, + keys: this.changedConfiguration.keys + }, + changedConfigurationByResource: this.changedConfigurationByResource.keys().reduce((result, resource) => { + const { contents, overrides, keys } = this.changedConfigurationByResource.get(resource); + result[resource.toString()] = { contents, overrides, keys }; + return result; + }, Object.create({})) + }; + } } \ No newline at end of file diff --git a/src/vs/workbench/api/electron-browser/mainThreadConfiguration.ts b/src/vs/workbench/api/electron-browser/mainThreadConfiguration.ts index a8b5cf06253..af38672d4b8 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadConfiguration.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadConfiguration.ts @@ -27,8 +27,8 @@ export class MainThreadConfiguration implements MainThreadConfigurationShape { ) { const proxy = extHostContext.get(ExtHostContext.ExtHostConfiguration); - this._configurationListener = configurationService.onDidChangeConfiguration(() => { - proxy.$acceptConfigurationChanged(configurationService.getConfigurationData()); + this._configurationListener = configurationService.onDidChangeConfiguration(e => { + proxy.$acceptConfigurationChanged(configurationService.getConfigurationData(), e.toJSON()); }); } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 5de663decdf..17980ed5b35 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -28,7 +28,7 @@ import * as editorCommon from 'vs/editor/common/editorCommon'; import * as modes from 'vs/editor/common/modes'; import { ITextSource } from 'vs/editor/common/model/textSource'; -import { IConfigurationData, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; +import { IConfigurationData, ConfigurationTarget, IConfigurationChangeEventData } from 'vs/platform/configuration/common/configuration'; import { IPickOpenEntry, IPickOptions } from 'vs/platform/quickOpen/common/quickOpen'; import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; @@ -418,7 +418,7 @@ export interface ExtHostCommandsShape { } export interface ExtHostConfigurationShape { - $acceptConfigurationChanged(data: IConfigurationData): void; + $acceptConfigurationChanged(data: IConfigurationData, eventData: IConfigurationChangeEventData): void; } export interface ExtHostDiagnosticsShape { diff --git a/src/vs/workbench/api/node/extHostConfiguration.ts b/src/vs/workbench/api/node/extHostConfiguration.ts index 55677b2d360..5a8dae4f23a 100644 --- a/src/vs/workbench/api/node/extHostConfiguration.ts +++ b/src/vs/workbench/api/node/extHostConfiguration.ts @@ -7,11 +7,11 @@ 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 * as vscode from 'vscode'; import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; import { ExtHostConfigurationShape, MainThreadConfigurationShape } from './extHost.protocol'; import { ConfigurationTarget as ExtHostConfigurationTarget } from './extHostTypes'; -import { IConfigurationData, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; +import { IConfigurationData, ConfigurationTarget, IConfigurationChangeEventData } from 'vs/platform/configuration/common/configuration'; import { Configuration } from 'vs/platform/configuration/common/configurationModels'; function lookUp(tree: any, key: string) { @@ -50,12 +50,12 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape { return this._onDidChangeConfiguration && this._onDidChangeConfiguration.event; } - $acceptConfigurationChanged(data: IConfigurationData) { + $acceptConfigurationChanged(data: IConfigurationData, eventData: IConfigurationChangeEventData) { this._configuration = Configuration.parse(data, this._extHostWorkspace.workspace); this._onDidChangeConfiguration.fire(undefined); } - getConfiguration(section?: string, resource?: URI): WorkspaceConfiguration { + getConfiguration(section?: string, resource?: URI): vscode.WorkspaceConfiguration { const config = section ? lookUp(this._configuration.getSection(null, { resource }), section) : this._configuration.getSection(null, { resource }); @@ -75,7 +75,7 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape { } } - const result: WorkspaceConfiguration = { + const result: vscode.WorkspaceConfiguration = { has(key: string): boolean { return typeof lookUp(config, key) !== 'undefined'; }, @@ -115,6 +115,6 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape { mixin(result, config, false); } - return Object.freeze(result); + return Object.freeze(result); } } diff --git a/src/vs/workbench/services/configuration/common/configurationModels.ts b/src/vs/workbench/services/configuration/common/configurationModels.ts index 8b9e5aa53fe..3cef3209dfe 100644 --- a/src/vs/workbench/services/configuration/common/configurationModels.ts +++ b/src/vs/workbench/services/configuration/common/configurationModels.ts @@ -5,7 +5,7 @@ 'use strict'; import { clone, equals } from 'vs/base/common/objects'; -import { compare, toValuesTree, IConfigurationChangeEvent, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; +import { compare, toValuesTree, IConfigurationChangeEvent, ConfigurationTarget, IConfigurationChangeEventData } from 'vs/platform/configuration/common/configuration'; import { ConfigurationModel, Configuration as BaseConfiguration, CustomConfigurationModel, ConfigurationChangeEvent } from 'vs/platform/configuration/common/configurationModels'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, IConfigurationPropertySchema, Extensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; @@ -270,7 +270,7 @@ export class Configuration extends BaseConfiguration { export class WorkspaceConfigurationChangeEvent implements IConfigurationChangeEvent { - constructor(private configurationChangeEvent: ConfigurationChangeEvent, private workspace: Workspace) { + constructor(private configurationChangeEvent: IConfigurationChangeEvent, private workspace: Workspace) { } get affectedKeys(): string[] { @@ -299,4 +299,22 @@ export class WorkspaceConfigurationChangeEvent implements IConfigurationChangeEv return false; } + + toJSON(): IConfigurationChangeEventData { + return this.configurationChangeEvent.toJSON(); + } + + public static parse(data: IConfigurationChangeEventData, workspace: Workspace): WorkspaceConfigurationChangeEvent { + const changedConfiguration = new ConfigurationModel(data.changedConfiguration.contents, data.changedConfiguration.keys, data.changedConfiguration.overrides); + const resources: URI[] = []; + const changedConfigurationByResource: StrictResourceMap = new StrictResourceMap(); + for (const key of Object.keys(data.changedConfigurationByResource)) { + const resource = URI.parse(key); + const model = data.changedConfigurationByResource[key]; + resources.push(resource); + changedConfigurationByResource.set(resource, new ConfigurationModel(model.contents, model.keys, model.overrides)); + } + const event = new ConfigurationChangeEvent(changedConfiguration, resources, changedConfigurationByResource); + return new WorkspaceConfigurationChangeEvent(event, workspace); + } } \ No newline at end of file