diff --git a/src/vs/editor/common/services/modeServiceImpl.ts b/src/vs/editor/common/services/modeServiceImpl.ts index afcd4caab6abbacdc4b239683f985983d7e64e65..d363aed0c9f3f7837ea80b60df2b0408126fd646 100644 --- a/src/vs/editor/common/services/modeServiceImpl.ts +++ b/src/vs/editor/common/services/modeServiceImpl.ts @@ -508,12 +508,11 @@ export class MainThreadModeServiceImpl extends ModeServiceImpl { public onReady(): TPromise { if (!this._onReadyPromise) { - this._onReadyPromise = this._configurationService.loadConfiguration().then((configuration: IFilesConfiguration) => { - return this._extensionService.onReady().then(() => { - this.onConfigurationChange(configuration); + const configuration = this._configurationService.getConfiguration(); + this._onReadyPromise = this._extensionService.onReady().then(() => { + this.onConfigurationChange(configuration); - return true; - }); + return true; }); } diff --git a/src/vs/editor/common/services/modelServiceImpl.ts b/src/vs/editor/common/services/modelServiceImpl.ts index 2eb9de5cc8325d3ec4d04b5aee49e82c2d8744ed..28dcae9ff76f5d8c7f703832784e54aadf326d0f 100644 --- a/src/vs/editor/common/services/modelServiceImpl.ts +++ b/src/vs/editor/common/services/modelServiceImpl.ts @@ -277,9 +277,7 @@ export class ModelServiceImpl implements IModelService { this._configurationServiceSubscription = this._configurationService.addListener2(ConfigurationServiceEventTypes.UPDATED, (e: IConfigurationServiceEvent) => { readConfig(e.config); }); - this._configurationService.loadConfiguration().then((config) => { - readConfig(config); - }); + readConfig(this._configurationService.getConfiguration()); this._models = {}; diff --git a/src/vs/platform/configuration/common/configuration.ts b/src/vs/platform/configuration/common/configuration.ts index 89036f2b69bc7bdd5012fcddb861c3661328637e..d1e3a8d59b0bd18a7d9bc8480d574165962cdab3 100644 --- a/src/vs/platform/configuration/common/configuration.ts +++ b/src/vs/platform/configuration/common/configuration.ts @@ -6,7 +6,6 @@ import {createDecorator, ServiceIdentifier} from 'vs/platform/instantiation/common/instantiation'; import {IEventEmitter} from 'vs/base/common/eventEmitter'; import Event from 'vs/base/common/event'; -import winjs = require('vs/base/common/winjs.base'); export const IConfigurationService = createDecorator('configurationService'); @@ -17,7 +16,7 @@ export interface IConfigurationService extends IEventEmitter { * Fetches the appropriate section of the configuration JSON file. * This will be an object keyed off the section name. */ - loadConfiguration(section?: string): winjs.TPromise; + getConfiguration(section?: string): T; /** * Returns iff the workspace has configuration or not. diff --git a/src/vs/platform/configuration/common/configurationService.ts b/src/vs/platform/configuration/common/configurationService.ts index e09f4732f4647ede63b34145335cae09a6948d76..487482b377ac585cfa9f3b15800969cea5375ca6 100644 --- a/src/vs/platform/configuration/common/configurationService.ts +++ b/src/vs/platform/configuration/common/configurationService.ts @@ -5,19 +5,19 @@ 'use strict'; import paths = require('vs/base/common/paths'); -import winjs = require('vs/base/common/winjs.base'); -import eventEmitter = require('vs/base/common/eventEmitter'); +import {TPromise} from 'vs/base/common/winjs.base'; +import {EventEmitter} from 'vs/base/common/eventEmitter'; import objects = require('vs/base/common/objects'); import errors = require('vs/base/common/errors'); import uri from 'vs/base/common/uri'; import model = require('./model'); import {RunOnceScheduler} from 'vs/base/common/async'; -import lifecycle = require('vs/base/common/lifecycle'); +import {IDisposable, cAll} from 'vs/base/common/lifecycle'; import collections = require('vs/base/common/collections'); import {IConfigurationService, ConfigurationServiceEventTypes} from './configuration'; import {IEventService} from 'vs/platform/event/common/event'; import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; -import Files = require('vs/platform/files/common/files'); +import {EventType, FileChangeType, FileChangesEvent} from 'vs/platform/files/common/files'; import {IConfigurationRegistry, Extensions} from './configurationRegistry'; import {Registry} from 'vs/platform/platform'; import Event, {fromEventEmitter} from 'vs/base/common/event'; @@ -42,7 +42,7 @@ interface ILoadConfigResult { globals: { contents: any; parseErrors: string[]; }; } -export abstract class ConfigurationService extends eventEmitter.EventEmitter implements IConfigurationService, lifecycle.IDisposable { +export abstract class ConfigurationService extends EventEmitter implements IConfigurationService, IDisposable { public serviceId = IConfigurationService; @@ -54,9 +54,10 @@ export abstract class ConfigurationService extends eventEmitter.EventEmitter imp protected eventService: IEventService; protected workspaceSettingsRootFolder: string; - private loadConfigurationPromise: winjs.TPromise; - private bulkFetchFromWorkspacePromise: winjs.TPromise; - private workspaceFilePathToConfiguration: { [relativeWorkspacePath: string]: winjs.TPromise }; + private cachedConfig: ILoadConfigResult; + + private bulkFetchFromWorkspacePromise: TPromise; + private workspaceFilePathToConfiguration: { [relativeWorkspacePath: string]: TPromise }; private callOnDispose: Function; private reloadConfigurationScheduler: RunOnceScheduler; @@ -68,102 +69,106 @@ export abstract class ConfigurationService extends eventEmitter.EventEmitter imp this.workspaceSettingsRootFolder = workspaceSettingsRootFolder; this.workspaceFilePathToConfiguration = Object.create(null); + this.cachedConfig = { + merged: {}, + consolidated: { contents: {}, parseErrors: [] }, + globals: { contents: {}, parseErrors: [] } + }; - let unbind = this.eventService.addListener(Files.EventType.FILE_CHANGES, (events) => this.handleFileEvents(events)); - let subscription = (Registry.as(Extensions.Configuration)).onDidRegisterConfiguration(() => this.reloadConfiguration()); + this.onDidUpdateConfiguration = fromEventEmitter(this, ConfigurationServiceEventTypes.UPDATED); + + this.registerListeners(); + } + + protected registerListeners(): void { + let unbind = this.eventService.addListener(EventType.FILE_CHANGES, (events) => this.handleFileEvents(events)); + let subscription = Registry.as(Extensions.Configuration).onDidRegisterConfiguration(() => this.handleConfigurationChange()); this.callOnDispose = () => { unbind(); subscription.dispose(); }; - - this.onDidUpdateConfiguration = fromEventEmitter(this, ConfigurationServiceEventTypes.UPDATED); } - protected abstract resolveContents(resource: uri[]): winjs.TPromise; - - protected abstract resolveContent(resource: uri): winjs.TPromise; + public initialize(): TPromise { + return this.loadConfiguration().then(() => null); + } - protected abstract resolveStat(resource: uri): winjs.TPromise; + protected abstract resolveContents(resource: uri[]): TPromise; - public dispose(): void { - if (this.reloadConfigurationScheduler) { - this.reloadConfigurationScheduler.dispose(); - } + protected abstract resolveContent(resource: uri): TPromise; - this.callOnDispose = lifecycle.cAll(this.callOnDispose); + protected abstract resolveStat(resource: uri): TPromise; - super.dispose(); - } + public getConfiguration(section?: string): T { + let result = section ? this.cachedConfig.merged[section] : this.cachedConfig.merged; - public loadConfiguration(section?: string): winjs.TPromise { - if (!this.loadConfigurationPromise) { - this.loadConfigurationPromise = this.doLoadConfiguration(); + let parseErrors = this.cachedConfig.consolidated.parseErrors; + if (this.cachedConfig.globals.parseErrors) { + parseErrors.push.apply(parseErrors, this.cachedConfig.globals.parseErrors); } - return this.loadConfigurationPromise.then((res: ILoadConfigResult) => { - let result = section ? res.merged[section] : res.merged; - - let parseErrors = res.consolidated.parseErrors; - if (res.globals.parseErrors) { - parseErrors.push.apply(parseErrors, res.globals.parseErrors); + if (parseErrors.length > 0) { + if (!result) { + result = {}; } + result.$parseErrors = parseErrors; + } - if (parseErrors.length > 0) { - if (!result) { - result = {}; - } - result.$parseErrors = parseErrors; - } + return result; + } - return result; + private loadConfiguration(section?: string): TPromise { + return this.doLoadConfiguration().then((res: ILoadConfigResult) => { + this.cachedConfig = res; + + return this.getConfiguration(section); }); } - private doLoadConfiguration(): winjs.TPromise { + private doLoadConfiguration(): TPromise { // Load globals - return this.loadGlobalConfiguration().then((globals) => { - - // Load workspace locals - return this.loadWorkspaceConfiguration().then((values) => { - - // Consolidate - let consolidated = model.consolidate(values); - - // Override with workspace locals - let merged = objects.mixin( - objects.clone(globals.contents), // target: global/default values (but dont modify!) - consolidated.contents, // source: workspace configured values - true // overwrite - ); - - return { - merged: merged, - consolidated: consolidated, - globals: globals - }; - }); + const globals = this.loadGlobalConfiguration(); + + // Load workspace locals + return this.loadWorkspaceConfiguration().then((values) => { + + // Consolidate + let consolidated = model.consolidate(values); + + // Override with workspace locals + let merged = objects.mixin( + objects.clone(globals.contents), // target: global/default values (but dont modify!) + consolidated.contents, // source: workspace configured values + true // overwrite + ); + + return { + merged: merged, + consolidated: consolidated, + globals: globals + }; }); } - protected loadGlobalConfiguration(): winjs.TPromise<{ contents: any; parseErrors: string[]; }> { - return winjs.TPromise.as({ + protected loadGlobalConfiguration(): { contents: any; parseErrors?: string[]; } { + return { contents: model.getDefaultValues() - }); + }; } public hasWorkspaceConfiguration(): boolean { return !!this.workspaceFilePathToConfiguration['.vscode/' + model.CONFIG_DEFAULT_NAME + '.json']; } - protected loadWorkspaceConfiguration(section?: string): winjs.TPromise<{ [relativeWorkspacePath: string]: model.IConfigFile }> { + protected loadWorkspaceConfiguration(section?: string): TPromise<{ [relativeWorkspacePath: string]: model.IConfigFile }> { // once: when invoked for the first time we fetch *all* json // files using the bulk stats and content routes if (!this.bulkFetchFromWorkspacePromise) { this.bulkFetchFromWorkspacePromise = this.resolveStat(this.contextService.toResource(this.workspaceSettingsRootFolder)).then((stat) => { if (!stat.isDirectory) { - return winjs.TPromise.as([]); + return TPromise.as([]); } return this.resolveContents(stat.children.filter((stat) => paths.extname(stat.resource.fsPath) === '.json').map(stat => stat.resource)); @@ -172,7 +177,7 @@ export abstract class ConfigurationService extends eventEmitter.EventEmitter imp return []; // never fail this call } }).then((contents: IContent[]) => { - contents.forEach(content => this.workspaceFilePathToConfiguration[this.contextService.toWorkspaceRelativePath(content.resource)] = winjs.TPromise.as(model.newConfigFile(content.value))); + contents.forEach(content => this.workspaceFilePathToConfiguration[this.contextService.toWorkspaceRelativePath(content.resource)] = TPromise.as(model.newConfigFile(content.value))); }, errors.onUnexpectedError); } @@ -180,14 +185,14 @@ export abstract class ConfigurationService extends eventEmitter.EventEmitter imp // we can merge them into a single configuration object. this // happens whenever a config file changes, is deleted, or added return this.bulkFetchFromWorkspacePromise.then(() => { - return winjs.TPromise.join(this.workspaceFilePathToConfiguration); + return TPromise.join(this.workspaceFilePathToConfiguration); }); } - protected reloadConfiguration(): void { + protected handleConfigurationChange(): void { if (!this.reloadConfigurationScheduler) { this.reloadConfigurationScheduler = new RunOnceScheduler(() => { - this.doReloadConfiguration().then((config) => this.emit(ConfigurationServiceEventTypes.UPDATED, { config: config })).done(null, errors.onUnexpectedError); + this.loadConfiguration().then((config) => this.emit(ConfigurationServiceEventTypes.UPDATED, { config: config })).done(null, errors.onUnexpectedError); }, ConfigurationService.RELOAD_CONFIGURATION_DELAY); } @@ -196,13 +201,7 @@ export abstract class ConfigurationService extends eventEmitter.EventEmitter imp } } - private doReloadConfiguration(section?: string): winjs.TPromise { - this.loadConfigurationPromise = null; - - return this.loadConfiguration(section); - } - - private handleFileEvents(event: Files.FileChangesEvent): void { + private handleFileEvents(event: FileChangesEvent): void { let events = event.changes; let affectedByChanges = false; for (let i = 0, len = events.length; i < len; i++) { @@ -212,7 +211,7 @@ export abstract class ConfigurationService extends eventEmitter.EventEmitter imp } // Handle case where ".vscode" got deleted - if (workspacePath === this.workspaceSettingsRootFolder && events[i].type === Files.FileChangeType.DELETED) { + if (workspacePath === this.workspaceSettingsRootFolder && events[i].type === FileChangeType.DELETED) { this.workspaceFilePathToConfiguration = Object.create(null); affectedByChanges = true; } @@ -225,18 +224,28 @@ export abstract class ConfigurationService extends eventEmitter.EventEmitter imp // insert 'fetch-promises' for add and update events and // remove promises for delete events switch (events[i].type) { - case Files.FileChangeType.DELETED: + case FileChangeType.DELETED: affectedByChanges = collections.remove(this.workspaceFilePathToConfiguration, workspacePath); break; - case Files.FileChangeType.UPDATED: - case Files.FileChangeType.ADDED: + case FileChangeType.UPDATED: + case FileChangeType.ADDED: this.workspaceFilePathToConfiguration[workspacePath] = this.resolveContent(events[i].resource).then(content => model.newConfigFile(content.value), errors.onUnexpectedError); affectedByChanges = true; } } if (affectedByChanges) { - this.reloadConfiguration(); + this.handleConfigurationChange(); } } + + public dispose(): void { + if (this.reloadConfigurationScheduler) { + this.reloadConfigurationScheduler.dispose(); + } + + this.callOnDispose = cAll(this.callOnDispose); + + super.dispose(); + } } diff --git a/src/vs/platform/keybinding/browser/keybindingServiceImpl.ts b/src/vs/platform/keybinding/browser/keybindingServiceImpl.ts index fda8ebe7f764b2ee231841c9c1db196d0d8a36d1..4f4a63506dfa95a89df59f37f18e7ed6194115b1 100644 --- a/src/vs/platform/keybinding/browser/keybindingServiceImpl.ts +++ b/src/vs/platform/keybinding/browser/keybindingServiceImpl.ts @@ -61,7 +61,7 @@ export class ConfigurationContext { constructor(configurationService: IConfigurationService) { this._subscription = configurationService.onDidUpdateConfiguration(e => this._updateConfigurationContext(e.config)); - configurationService.loadConfiguration().then(config => this._updateConfigurationContext(config)); + this._updateConfigurationContext(configurationService.getConfiguration()); } public dispose() { diff --git a/src/vs/platform/telemetry/electron-browser/electronTelemetryService.ts b/src/vs/platform/telemetry/electron-browser/electronTelemetryService.ts index 9b2c35b0bfdcb24c7356aea65038e92b5a69cb1c..1dce61eda6a3aa4965b3c57ac23d689266057db6 100644 --- a/src/vs/platform/telemetry/electron-browser/electronTelemetryService.ts +++ b/src/vs/platform/telemetry/electron-browser/electronTelemetryService.ts @@ -77,12 +77,11 @@ export class ElectronTelemetryService extends MainTelemetryService implements IT } private loadOptinSettings(): void { - this.configurationService.loadConfiguration(TELEMETRY_SECTION_ID).done(config => { - this.config.userOptIn = config ? config.enableTelemetry : this.config.userOptIn; - this._optInStatusLoaded = true; - this.publicLog('optInStatus', {optIn: this.config.userOptIn}); - this.flushBuffer(); - }); + const config = this.configurationService.getConfiguration(TELEMETRY_SECTION_ID); + this.config.userOptIn = config ? config.enableTelemetry : this.config.userOptIn; + this._optInStatusLoaded = true; + this.publicLog('optInStatus', {optIn: this.config.userOptIn}); + this.flushBuffer(); this.toUnbind.push(this.configurationService.addListener(ConfigurationServiceEventTypes.UPDATED, (e: IConfigurationServiceEvent) => { this.config.userOptIn = e.config && e.config[TELEMETRY_SECTION_ID] ? e.config[TELEMETRY_SECTION_ID].enableTelemetry : this.config.userOptIn; diff --git a/src/vs/workbench/api/node/extHostConfiguration.ts b/src/vs/workbench/api/node/extHostConfiguration.ts index 4fb3417fb4ff718efe5eb970673168f8199c9ea8..332e0d86f027a26bcbf84cf67c1d00abccefcc1a 100644 --- a/src/vs/workbench/api/node/extHostConfiguration.ts +++ b/src/vs/workbench/api/node/extHostConfiguration.ts @@ -88,9 +88,7 @@ export class MainThreadConfiguration { this._toDispose.push(this._configurationService.addListener2(ConfigurationServiceEventTypes.UPDATED, (e:IConfigurationServiceEvent) => { this._proxy._acceptConfigurationChanged(e.config); })); - this._configurationService.loadConfiguration().then((config) => { - this._proxy._acceptConfigurationChanged(config); - }); + this._proxy._acceptConfigurationChanged(this._configurationService.getConfiguration()); } public dispose(): void { diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index 537cbc566464ee5b8d42a4932c9e452f079a2c28..9fed240e8230c2c62b7cffd57c0018b09319b0a8 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -102,7 +102,7 @@ class StateChange { this.tabFocusMode = false; } - public combine(other:StateChange) { + public combine(other: StateChange) { this.indentation = this.indentation || other.indentation; this.selectionStatus = this.selectionStatus || other.selectionStatus; this.mode = this.mode || other.mode; @@ -321,7 +321,7 @@ export class EditorStatus implements IStatusbarItem { } } - private _renderNow(changed:StateChange): void { + private _renderNow(changed: StateChange): void { if (changed.tabFocusMode) { if (this.state.tabFocusMode && this.state.tabFocusMode === true) { show(this.tabFocusModeElement); @@ -488,7 +488,7 @@ export class EditorStatus implements IStatusbarItem { update.indentation = ( modelOpts.insertSpaces ? nls.localize('spacesSize', "Spaces: {0}", modelOpts.tabSize) - : nls.localize({ key: 'tabSize', comment: ['Tab corresponds to the tab key']}, "Tab Size: {0}", modelOpts.tabSize) + : nls.localize({ key: 'tabSize', comment: ['Tab corresponds to the tab key'] }, "Tab Size: {0}", modelOpts.tabSize) ); } } @@ -868,49 +868,48 @@ export class ChangeEncodingAction extends Action { } return TPromise.timeout(50 /* quick open is sensitive to being opened so soon after another */).then(() => { + const configuration = this.configurationService.getConfiguration(); + let isReopenWithEncoding = (action === reopenWithEncodingPick); + let configuredEncoding = configuration && configuration.files && configuration.files.encoding; + let directMatchIndex: number; + let aliasMatchIndex: number; + + // All encodings are valid picks + let picks: IPickOpenEntry[] = Object.keys(SUPPORTED_ENCODINGS) + .sort((k1, k2) => { + if (k1 === configuredEncoding) { + return -1; + } else if (k2 === configuredEncoding) { + return 1; + } - return this.configurationService.loadConfiguration().then((configuration: IFilesConfiguration) => { - let configuredEncoding = configuration && configuration.files && configuration.files.encoding; - let directMatchIndex: number; - let aliasMatchIndex: number; - - // All encodings are valid picks - let picks: IPickOpenEntry[] = Object.keys(SUPPORTED_ENCODINGS) - .sort((k1, k2) => { - if (k1 === configuredEncoding) { - return -1; - } else if (k2 === configuredEncoding) { - return 1; - } - - return SUPPORTED_ENCODINGS[k1].order - SUPPORTED_ENCODINGS[k2].order; - }) - .filter(k => { - return !isReopenWithEncoding || !SUPPORTED_ENCODINGS[k].encodeOnly; // hide those that can only be used for encoding if we are about to decode - }) - .map((key, index) => { - if (key === encodingSupport.getEncoding()) { - directMatchIndex = index; - } else if (SUPPORTED_ENCODINGS[key].alias === encodingSupport.getEncoding()) { - aliasMatchIndex = index; - } - - return { id: key, label: SUPPORTED_ENCODINGS[key].labelLong }; - }); - - return this.quickOpenService.pick(picks, { - placeHolder: isReopenWithEncoding ? nls.localize('pickEncodingForReopen', "Select File Encoding to Reopen File") : nls.localize('pickEncodingForSave', "Select File Encoding to Save with"), - autoFocus: { autoFocusIndex: typeof directMatchIndex === 'number' ? directMatchIndex : typeof aliasMatchIndex === 'number' ? aliasMatchIndex : void 0 } - }).then((encoding) => { - if (encoding) { - activeEditor = this.editorService.getActiveEditor(); - encodingSupport = asFileOrUntitledEditorInput(activeEditor.input); - if (encodingSupport && types.areFunctions(encodingSupport.setEncoding, encodingSupport.getEncoding) && encodingSupport.getEncoding() !== encoding.id) { - encodingSupport.setEncoding(encoding.id, isReopenWithEncoding ? EncodingMode.Decode : EncodingMode.Encode); // Set new encoding - } + return SUPPORTED_ENCODINGS[k1].order - SUPPORTED_ENCODINGS[k2].order; + }) + .filter(k => { + return !isReopenWithEncoding || !SUPPORTED_ENCODINGS[k].encodeOnly; // hide those that can only be used for encoding if we are about to decode + }) + .map((key, index) => { + if (key === encodingSupport.getEncoding()) { + directMatchIndex = index; + } else if (SUPPORTED_ENCODINGS[key].alias === encodingSupport.getEncoding()) { + aliasMatchIndex = index; } + + return { id: key, label: SUPPORTED_ENCODINGS[key].labelLong }; }); + + return this.quickOpenService.pick(picks, { + placeHolder: isReopenWithEncoding ? nls.localize('pickEncodingForReopen', "Select File Encoding to Reopen File") : nls.localize('pickEncodingForSave', "Select File Encoding to Save with"), + autoFocus: { autoFocusIndex: typeof directMatchIndex === 'number' ? directMatchIndex : typeof aliasMatchIndex === 'number' ? aliasMatchIndex : void 0 } + }).then((encoding) => { + if (encoding) { + activeEditor = this.editorService.getActiveEditor(); + encodingSupport = asFileOrUntitledEditorInput(activeEditor.input); + if (encodingSupport && types.areFunctions(encodingSupport.setEncoding, encodingSupport.getEncoding) && encodingSupport.getEncoding() !== encoding.id) { + encodingSupport.setEncoding(encoding.id, isReopenWithEncoding ? EncodingMode.Decode : EncodingMode.Encode); // Set new encoding + } + } }); }); }); diff --git a/src/vs/workbench/browser/parts/editor/textEditor.ts b/src/vs/workbench/browser/parts/editor/textEditor.ts index d44c23c43b1567495c8b898736ea07ca9a7b1e48..5f5d3ff004d699901aeaf9e6c38f569bd867e864 100644 --- a/src/vs/workbench/browser/parts/editor/textEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textEditor.ts @@ -9,7 +9,6 @@ import 'vs/css!./media/texteditor'; import {TPromise} from 'vs/base/common/winjs.base'; import {Dimension, Builder} from 'vs/base/browser/builder'; import objects = require('vs/base/common/objects'); -import errors = require('vs/base/common/errors'); import {CodeEditorWidget} from 'vs/editor/browser/widget/codeEditorWidget'; import {Preferences} from 'vs/workbench/common/constants'; import {IEditorViewState} from 'vs/editor/common/editorCommon'; @@ -164,9 +163,7 @@ export abstract class BaseTextEditor extends BaseEditor { })); // Configuration - this.configurationService.loadConfiguration().then((config) => { - this.applyConfiguration(config); - }, errors.onUnexpectedError); + this.applyConfiguration(this.configurationService.getConfiguration()); } /** diff --git a/src/vs/workbench/common/editor/untitledEditorModel.ts b/src/vs/workbench/common/editor/untitledEditorModel.ts index 4e2e017d14fb164f4e327eb69a67e1877907bedc..f91bba6b471b4f846cffcb799483f1ddd26126db 100644 --- a/src/vs/workbench/common/editor/untitledEditorModel.ts +++ b/src/vs/workbench/common/editor/untitledEditorModel.ts @@ -87,23 +87,22 @@ export class UntitledEditorModel extends StringEditorModel implements IEncodingS public load(): TPromise { return super.load().then((model) => { - return this.configurationService.loadConfiguration().then((configuration: IFilesConfiguration) => { + const configuration = this.configurationService.getConfiguration(); - // Encoding - this.configuredEncoding = configuration && configuration.files && configuration.files.encoding; + // Encoding + this.configuredEncoding = configuration && configuration.files && configuration.files.encoding; - // Listen to content changes - this.textModelChangeListener = this.textEditorModel.addListener(EventType.ModelContentChanged, (e: IModelContentChangedEvent) => this.onModelContentChanged(e)); + // Listen to content changes + this.textModelChangeListener = this.textEditorModel.addListener(EventType.ModelContentChanged, (e: IModelContentChangedEvent) => this.onModelContentChanged(e)); - // Emit initial dirty event if we are - if (this.dirty) { - setTimeout(() => { - this.eventService.emit(WorkbenchEventType.UNTITLED_FILE_DIRTY, new UntitledEditorEvent(this.resource)); - }, 0 /* prevent race condition between creating model and emitting dirty event */); - } + // Emit initial dirty event if we are + if (this.dirty) { + setTimeout(() => { + this.eventService.emit(WorkbenchEventType.UNTITLED_FILE_DIRTY, new UntitledEditorEvent(this.resource)); + }, 0 /* prevent race condition between creating model and emitting dirty event */); + } - return model; - }); + return model; }); } diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index 565fbc87a9c4f2cf115ffa75c30a0dc000caab03..b4a77572480444fe7fd1a36d869f20dd523a2034 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -186,14 +186,13 @@ export abstract class BaseZoomAction extends Action { return TPromise.as(false); // Subclass to implement } - protected loadConfiguredZoomLevel(): TPromise { - return this.configurationService.loadConfiguration().then((windowConfig: IWindowConfiguration) => { - if (windowConfig.window && typeof windowConfig.window.zoomLevel === 'number') { - return windowConfig.window.zoomLevel; - } + protected getConfiguredZoomLevel(): number { + const windowConfig = this.configurationService.getConfiguration(); + if (windowConfig.window && typeof windowConfig.window.zoomLevel === 'number') { + return windowConfig.window.zoomLevel; + } - return 0; // default - }); + return 0; // default } } @@ -211,16 +210,16 @@ export class ZoomOutAction extends BaseZoomAction { } public run(): TPromise { - return this.loadConfiguredZoomLevel().then(level => { - let newZoomLevelCandiate = webFrame.getZoomLevel() - 1; - if (newZoomLevelCandiate < 0 && newZoomLevelCandiate < level) { - newZoomLevelCandiate = Math.min(level, 0); // do not zoom below configured level or below 0 - } + const level = this.getConfiguredZoomLevel(); - webFrame.setZoomLevel(newZoomLevelCandiate); + let newZoomLevelCandiate = webFrame.getZoomLevel() - 1; + if (newZoomLevelCandiate < 0 && newZoomLevelCandiate < level) { + newZoomLevelCandiate = Math.min(level, 0); // do not zoom below configured level or below 0 + } - return true; - }); + webFrame.setZoomLevel(newZoomLevelCandiate); + + return TPromise.as(true); } } @@ -238,11 +237,10 @@ export class ZoomResetAction extends BaseZoomAction { } public run(): TPromise { - return this.loadConfiguredZoomLevel().then(level => { - webFrame.setZoomLevel(level); + const level = this.getConfiguredZoomLevel(); + webFrame.setZoomLevel(level); - return true; - }); + return TPromise.as(true); } } diff --git a/src/vs/workbench/electron-browser/crashReporter.ts b/src/vs/workbench/electron-browser/crashReporter.ts index ac70aec787fe8ac9ee8c12314e77cf1b519aa4ee..bd00d5b37e8c75b1aec0abcc24a3c51960e56355 100644 --- a/src/vs/workbench/electron-browser/crashReporter.ts +++ b/src/vs/workbench/electron-browser/crashReporter.ts @@ -53,12 +53,10 @@ export class CrashReporter { public start(rawConfiguration:Electron.CrashReporterStartOptions): void { if (!this.isStarted) { if (!this.config) { - this.configurationService.loadConfiguration(TELEMETRY_SECTION_ID).done((c) => { - this.config = c; - if (this.config && this.config.enableCrashReporter) { - this.doStart(rawConfiguration); - } - }); + this.config = this.configurationService.getConfiguration(TELEMETRY_SECTION_ID); + if (this.config && this.config.enableCrashReporter) { + this.doStart(rawConfiguration); + } } else { if (this.config.enableCrashReporter) { this.doStart(rawConfiguration); diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 1349538ae913327ebf372802b5ba0ceab0041d8f..c72a070c29b6e8ba40b27193c4ae83eabf119cee 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -17,7 +17,10 @@ import uri from 'vs/base/common/uri'; import strings = require('vs/base/common/strings'); import {IResourceInput} from 'vs/platform/editor/common/editor'; import {IEnv} from 'vs/base/node/env'; +import {EventService} from 'vs/platform/event/common/eventService'; +import {WorkspaceContextService} from 'vs/workbench/services/workspace/common/contextService'; import {IWorkspace, IConfiguration, IEnvironment} from 'vs/platform/workspace/common/workspace'; +import {ConfigurationService} from 'vs/workbench/services/configuration/node/configurationService'; import path = require('path'); import fs = require('fs'); @@ -25,6 +28,9 @@ import fs = require('fs'); import gracefulFs = require('graceful-fs'); gracefulFs.gracefulify(fs); +const timers = (window).MonacoEnvironment.timers; +const domContentLoaded: Function = (winjs).Utilities.ready; + export interface IPath { filePath: string; lineNumber?: number; @@ -50,7 +56,6 @@ export function startup(environment: IMainEnvironment, globalSettings: IGlobalSe env: environment }; - // Shell Options let filesToOpen = environment.filesToOpen && environment.filesToOpen.length ? toInputs(environment.filesToOpen) : null; let filesToCreate = environment.filesToCreate && environment.filesToCreate.length ? toInputs(environment.filesToCreate) : null; @@ -121,27 +126,39 @@ function getWorkspace(environment: IMainEnvironment): IWorkspace { } function openWorkbench(workspace: IWorkspace, configuration: IConfiguration, options: IOptions): winjs.TPromise { - (window).MonacoEnvironment.timers.beforeReady = new Date(); - - return (winjs).Utilities.ready(() => { - (window).MonacoEnvironment.timers.afterReady = new Date(); - - // Monaco Workbench Shell - let beforeOpen = new Date(); - let shell = new WorkbenchShell(document.body, workspace, configuration, options); - shell.open(); - - shell.joinCreation().then(() => { - timer.start(timer.Topic.STARTUP, 'Open Shell, Viewlet & Editor', beforeOpen, 'Workbench has opened after this event with viewlet and editor restored').stop(); - }); - - // Inform user about loading issues from the loader - (self).require.config({ - onError: (err: any) => { - if (err.errorCode === 'load') { - shell.onUnexpectedError(errors.loaderError(err)); + let eventService = new EventService(); + let contextService = new WorkspaceContextService(eventService, workspace, configuration, options); + let configurationService = new ConfigurationService(contextService, eventService); + + // Since the configuration service is one of the core services that is used in so many places, we initialize it + // right before startup of the workbench shell to have its data ready for consumers + return configurationService.initialize().then(() => { + timers.beforeReady = new Date(); + + return domContentLoaded(() => { + timers.afterReady = new Date(); + + // Open Shell + let beforeOpen = new Date(); + let shell = new WorkbenchShell(document.body, workspace, { + configurationService, + eventService, + contextService + }, configuration, options); + shell.open(); + + shell.joinCreation().then(() => { + timer.start(timer.Topic.STARTUP, 'Open Shell, Viewlet & Editor', beforeOpen, 'Workbench has opened after this event with viewlet and editor restored').stop(); + }); + + // Inform user about loading issues from the loader + (self).require.config({ + onError: (err: any) => { + if (err.errorCode === 'load') { + shell.onUnexpectedError(errors.loaderError(err)); + } } - } - }); - }, true); + }); + }, true); + }); } \ No newline at end of file diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index b22e3f5dcf14bb6d6693829ea43715ff47b14cce..1a82f8435579e6fbbe10e12021c9664003a78572 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -14,7 +14,6 @@ import 'vs/css!vs/workbench/browser/media/hc-black-theme'; import * as nls from 'vs/nls'; import {TPromise} from 'vs/base/common/winjs.base'; import {Dimension, Builder, $} from 'vs/base/browser/builder'; -import objects = require('vs/base/common/objects'); import dom = require('vs/base/browser/dom'); import aria = require('vs/base/browser/ui/aria/aria'); import {dispose, IDisposable} from 'vs/base/common/lifecycle'; @@ -34,7 +33,6 @@ import {IWindowService, WindowService} from 'vs/workbench/services/window/electr import {MessageService} from 'vs/workbench/services/message/electron-browser/messageService'; import {RequestService} from 'vs/workbench/services/request/node/requestService'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; -import {ConfigurationService} from 'vs/workbench/services/configuration/node/configurationService'; import {FileService} from 'vs/workbench/services/files/electron-browser/fileService'; import {SearchService} from 'vs/workbench/services/search/node/searchService'; import {LifecycleService} from 'vs/workbench/services/lifecycle/electron-browser/lifecycleService'; @@ -69,9 +67,7 @@ import {MainThreadEditors} from 'vs/workbench/api/node/extHostEditors'; import {MainThreadWorkspace} from 'vs/workbench/api/node/extHostWorkspace'; import {MainThreadConfiguration} from 'vs/workbench/api/node/extHostConfiguration'; import {MainThreadLanguageFeatures} from 'vs/workbench/api/node/extHostLanguageFeatures'; -import {EventService} from 'vs/platform/event/common/eventService'; import {IOptions} from 'vs/workbench/common/options'; -import {WorkspaceContextService} from 'vs/workbench/services/workspace/common/contextService'; import {IStorageService, StorageScope, StorageEvent, StorageEventType} from 'vs/platform/storage/common/storage'; import {MainThreadStorage} from 'vs/platform/storage/common/remotable.storage'; import {IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -100,6 +96,15 @@ import {IExtensionsService} from 'vs/workbench/parts/extensions/common/extension import {ExtensionsService} from 'vs/workbench/parts/extensions/node/extensionsService'; import {ReloadWindowAction} from 'vs/workbench/electron-browser/actions'; +/** + * Services that we require for the Shell + */ +export interface ICoreServices { + contextService: IWorkspaceContextService; + eventService: IEventService; + configurationService: IConfigurationService; +} + /** * The Monaco Workbench Shell contains the Monaco workbench with a rich header containing navigation and the activity bar. * With the Shell being the top level element in the page, it is also responsible for driving the layouting. @@ -107,11 +112,13 @@ import {ReloadWindowAction} from 'vs/workbench/electron-browser/actions'; export class WorkbenchShell { private storageService: IStorageService; private messageService: IMessageService; + private eventService: IEventService; private contextViewService: ContextViewService; private windowService: IWindowService; private threadService: MainThreadService; + private configurationService: IConfigurationService; private themeService: IThemeService; - private contextService: WorkspaceContextService; + private contextService: IWorkspaceContextService; private telemetryService: ElectronTelemetryService; private keybindingService: WorkbenchKeybindingService; @@ -128,12 +135,16 @@ export class WorkbenchShell { private options: IOptions; private workbench: Workbench; - constructor(container: HTMLElement, workspace: IWorkspace, configuration: IConfiguration, options: IOptions) { + constructor(container: HTMLElement, workspace: IWorkspace, services: ICoreServices, configuration: IConfiguration, options: IOptions) { this.container = container; this.workspace = workspace; this.configuration = configuration; - this.options = objects.mixin({}, options); + this.options = options; + + this.contextService = services.contextService; + this.eventService = services.eventService; + this.configurationService = services.configurationService; this.toUnbind = []; this.previousErrorTime = 0; @@ -221,32 +232,23 @@ export class WorkbenchShell { } private initInstantiationService(): IInstantiationService { - let eventService = new EventService(); - - this.contextService = new WorkspaceContextService(eventService, this.workspace, this.configuration, this.options); - this.windowService = new WindowService(); let disableWorkspaceStorage = this.configuration.env.extensionTestsPath || (!this.workspace && !this.configuration.env.extensionDevelopmentPath); // without workspace or in any extension test, we use inMemory storage unless we develop an extension where we want to preserve state this.storageService = new Storage(this.contextService, window.localStorage, disableWorkspaceStorage ? inMemoryLocalStorageInstance : window.localStorage); - let configService = new ConfigurationService( - this.contextService, - eventService - ); - // no telemetry in a window for extension development! let enableTelemetry = this.configuration.env.isBuilt && !this.configuration.env.extensionDevelopmentPath ? !!this.configuration.env.enableTelemetry : false; - this.telemetryService = new ElectronTelemetryService(configService, this.storageService, { enableTelemetry: enableTelemetry, version: this.configuration.env.version, commitHash: this.configuration.env.commitHash }); + this.telemetryService = new ElectronTelemetryService(this.configurationService, this.storageService, { enableTelemetry: enableTelemetry, version: this.configuration.env.version, commitHash: this.configuration.env.commitHash }); - this.keybindingService = new WorkbenchKeybindingService(configService, this.contextService, eventService, this.telemetryService, window); + this.keybindingService = new WorkbenchKeybindingService(this.configurationService, this.contextService, this.configurationService, this.telemetryService, window); this.messageService = new MessageService(this.contextService, this.windowService, this.telemetryService, this.keybindingService); this.keybindingService.setMessageService(this.messageService); let fileService = new FileService( - configService, - eventService, + this.configurationService, + this.eventService, this.contextService ); @@ -259,7 +261,7 @@ export class WorkbenchShell { let requestService = new RequestService( this.contextService, - configService, + this.configurationService, this.telemetryService ); lifecycleService.onShutdown(() => requestService.dispose()); @@ -269,8 +271,8 @@ export class WorkbenchShell { let extensionService = new MainProcessExtensionService(this.contextService, this.threadService, this.messageService, this.telemetryService); this.keybindingService.setExtensionService(extensionService); - let modeService = new MainThreadModeServiceImpl(this.threadService, extensionService, configService); - let modelService = new ModelServiceImpl(this.threadService, markerService, modeService, configService, this.messageService); + let modeService = new MainThreadModeServiceImpl(this.threadService, extensionService, this.configurationService); + let modelService = new ModelServiceImpl(this.threadService, markerService, modeService, this.configurationService, this.messageService); let editorWorkerService = new EditorWorkerServiceImpl(modelService); let untitledEditorService = new UntitledEditorService(); @@ -278,7 +280,7 @@ export class WorkbenchShell { let result = createInstantiationService(); result.addSingleton(ITelemetryService, this.telemetryService); - result.addSingleton(IEventService, eventService); + result.addSingleton(IEventService, this.eventService); result.addSingleton(IRequestService, requestService); result.addSingleton(IWorkspaceContextService, this.contextService); result.addSingleton(IContextViewService, this.contextViewService); @@ -291,9 +293,9 @@ export class WorkbenchShell { result.addSingleton(IModeService, modeService); result.addSingleton(IFileService, fileService); result.addSingleton(IUntitledEditorService, untitledEditorService); - result.addSingleton(ISearchService, new SearchService(modelService, untitledEditorService, this.contextService, configService)); + result.addSingleton(ISearchService, new SearchService(modelService, untitledEditorService, this.contextService, this.configurationService)); result.addSingleton(IWindowService, this.windowService); - result.addSingleton(IConfigurationService, configService); + result.addSingleton(IConfigurationService, this.configurationService); result.addSingleton(IKeybindingService, this.keybindingService); result.addSingleton(IMarkerService, markerService); result.addSingleton(IModelService, modelService); diff --git a/src/vs/workbench/parts/debug/node/debugConfigurationManager.ts b/src/vs/workbench/parts/debug/node/debugConfigurationManager.ts index 7cd5a8a06c1f93bffc3798c5e1bda75e7b32d43a..4e3693761f33753389f15b5124d8cc20d08b0f20 100644 --- a/src/vs/workbench/parts/debug/node/debugConfigurationManager.ts +++ b/src/vs/workbench/parts/debug/node/debugConfigurationManager.ts @@ -337,6 +337,6 @@ export class ConfigurationManager { } public loadLaunchConfig(): TPromise { - return this.configurationService.loadConfiguration('launch'); + return TPromise.as(this.configurationService.getConfiguration('launch')); } } diff --git a/src/vs/workbench/parts/files/browser/textFileServices.ts b/src/vs/workbench/parts/files/browser/textFileServices.ts index 222fccae41a9ed0c363405c7e5d432025da5e138..2e2239b31e69bb10b1dc593465855048520c37c6 100644 --- a/src/vs/workbench/parts/files/browser/textFileServices.ts +++ b/src/vs/workbench/parts/files/browser/textFileServices.ts @@ -53,7 +53,12 @@ export abstract class TextFileService implements ITextFileService { protected init(): void { this.registerListeners(); - this.loadConfiguration(); + + const configuration = this.configurationService.getConfiguration(); + this.onConfigurationChange(configuration); + + // we want to find out about this setting from telemetry + this.telemetryService.publicLog('autoSave', this.getAutoSaveConfiguration()); } public get onAutoSaveConfigurationChange(): Event { @@ -88,15 +93,6 @@ export abstract class TextFileService implements ITextFileService { } } - private loadConfiguration(): void { - this.configurationService.loadConfiguration().done((configuration: IFilesConfiguration) => { - this.onConfigurationChange(configuration); - - // we want to find out about this setting from telemetry - this.telemetryService.publicLog('autoSave', this.getAutoSaveConfiguration()); - }, errors.onUnexpectedError); - } - private onConfigurationChange(configuration: IFilesConfiguration): void { const wasAutoSaveEnabled = (this.getAutoSaveMode() !== AutoSaveMode.OFF); @@ -254,7 +250,7 @@ export abstract class TextFileService implements ITextFileService { } if (this.configuredAutoSaveDelay && this.configuredAutoSaveDelay > 0) { - return this.configuredAutoSaveDelay <= 1000 ? AutoSaveMode.AFTER_SHORT_DELAY : AutoSaveMode.AFTER_LONG_DELAY; + return this.configuredAutoSaveDelay <= 1000 ? AutoSaveMode.AFTER_SHORT_DELAY : AutoSaveMode.AFTER_LONG_DELAY; } return AutoSaveMode.OFF; diff --git a/src/vs/workbench/parts/files/browser/views/explorerView.ts b/src/vs/workbench/parts/files/browser/views/explorerView.ts index 48e7578158f840a5fd31d6755f4b75e2bb23a82a..e4e34d323c627102042112718cd9aa210b1d69f8 100644 --- a/src/vs/workbench/parts/files/browser/views/explorerView.ts +++ b/src/vs/workbench/parts/files/browser/views/explorerView.ts @@ -130,21 +130,18 @@ export class ExplorerView extends CollapsibleViewletView { public create(): TPromise { - // Load Config - return this.configurationService.loadConfiguration().then((configuration: IFilesConfiguration) => { + // Update configuration + const configuration = this.configurationService.getConfiguration(); + this.onConfigurationUpdated(configuration); - // Update configuration - this.onConfigurationUpdated(configuration); + // Load and Fill Viewer + return this.refresh(false, false).then(() => { - // Load and Fill Viewer - return this.refresh(false, false).then(() => { + // When the explorer viewer is loaded, listen to changes to the editor input + this.toDispose.push(this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_CHANGING, (e: EditorEvent) => this.onEditorInputChanging(e))); - // When the explorer viewer is loaded, listen to changes to the editor input - this.toDispose.push(this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_CHANGING, (e: EditorEvent) => this.onEditorInputChanging(e))); - - // Also handle configuration updates - this.toDispose.push(this.configurationService.addListener2(ConfigurationServiceEventTypes.UPDATED, (e: IConfigurationServiceEvent) => this.onConfigurationUpdated(e.config, true))); - }); + // Also handle configuration updates + this.toDispose.push(this.configurationService.addListener2(ConfigurationServiceEventTypes.UPDATED, (e: IConfigurationServiceEvent) => this.onConfigurationUpdated(e.config, true))); }); } @@ -316,9 +313,9 @@ export class ExplorerView extends CollapsibleViewletView { dnd: dnd, accessibilityProvider: accessibility }, { - autoExpandSingleChildren: true, - ariaLabel: nls.localize('treeAriaLabel', "Files Explorer") - }); + autoExpandSingleChildren: true, + ariaLabel: nls.localize('treeAriaLabel', "Files Explorer") + }); this.toDispose.push(lifecycle.toDisposable(() => renderer.dispose())); diff --git a/src/vs/workbench/parts/files/browser/views/workingFilesView.ts b/src/vs/workbench/parts/files/browser/views/workingFilesView.ts index bfe6f722dc489fbe662ef2d4ca2c4d1a12583c0f..f8816c12b70ed63635da922f334748b9b6ee1bb4 100644 --- a/src/vs/workbench/parts/files/browser/views/workingFilesView.ts +++ b/src/vs/workbench/parts/files/browser/views/workingFilesView.ts @@ -90,19 +90,16 @@ export class WorkingFilesView extends AdaptiveCollapsibleViewletView { public create(): TPromise { // Load Config - return this.configurationService.loadConfiguration().then((configuration) => { + const configuration = this.configurationService.getConfiguration(); + this.onConfigurationUpdated(configuration); - // Update configuration - this.onConfigurationUpdated(configuration); + // listeners + this.registerListeners(); - // listeners - this.registerListeners(); + // highlight active input + this.highlightInput(this.editorService.getActiveEditorInput()); - // highlight active input - this.highlightInput(this.editorService.getActiveEditorInput()); - - return super.create(); - }); + return super.create(); } private onConfigurationUpdated(configuration: IFilesConfiguration): void { @@ -296,10 +293,10 @@ export class WorkingFilesView extends AdaptiveCollapsibleViewletView { dnd: dnd, accessibilityProvider: accessibility }, { - indentPixels: 0, - twistiePixels: 8, - ariaLabel: nls.localize('treeAriaLabel', "Working Files") - }); + indentPixels: 0, + twistiePixels: 8, + ariaLabel: nls.localize('treeAriaLabel', "Working Files") + }); this.tree.setInput(this.model); diff --git a/src/vs/workbench/parts/files/common/editors/saveParticipant.ts b/src/vs/workbench/parts/files/common/editors/saveParticipant.ts index 8438c60305cf7712c323f200e170d0df82826b61..db3f2cf10b362e941f51e456d4a5ad1f8e15cc3b 100644 --- a/src/vs/workbench/parts/files/common/editors/saveParticipant.ts +++ b/src/vs/workbench/parts/files/common/editors/saveParticipant.ts @@ -2,12 +2,11 @@ * 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 {IWorkbenchContribution} from 'vs/workbench/common/contributions'; import {ICodeEditorService} from 'vs/editor/common/services/codeEditorService'; -import errors = require('vs/base/common/errors'); import {TextFileChangeEvent, EventType} from 'vs/workbench/parts/files/common/files'; import {IFilesConfiguration} from 'vs/platform/files/common/files'; import {IPosition, IEditorSelection, IModel} from 'vs/editor/common/editorCommon'; @@ -30,7 +29,7 @@ export class SaveParticipant implements IWorkbenchContribution { this.trimTrailingWhitespace = false; this.registerListeners(); - this.loadConfiguration(); + this.onConfigurationChange(this.configurationService.getConfiguration()); } private registerListeners(): void { @@ -38,12 +37,6 @@ export class SaveParticipant implements IWorkbenchContribution { this.toUnbind.push(this.configurationService.addListener(ConfigurationServiceEventTypes.UPDATED, (e: IConfigurationServiceEvent) => this.onConfigurationChange(e.config))); } - private loadConfiguration(): void { - this.configurationService.loadConfiguration().done((configuration: IFilesConfiguration) => { - this.onConfigurationChange(configuration); - }, errors.onUnexpectedError); - } - private onConfigurationChange(configuration: IFilesConfiguration): void { this.trimTrailingWhitespace = configuration && configuration.files && configuration.files.trimTrailingWhitespace; } diff --git a/src/vs/workbench/parts/git/browser/gitServices.ts b/src/vs/workbench/parts/git/browser/gitServices.ts index c1d11bf2fba16bb51b0981b76d111ee6b3f382b2..b4edc23e840b9e7fb0f12bdefa5606b296fe3ed1 100644 --- a/src/vs/workbench/parts/git/browser/gitServices.ts +++ b/src/vs/workbench/parts/git/browser/gitServices.ts @@ -275,7 +275,7 @@ export class AutoFetcher implements git.IAutoFetcher, lifecycle.IDisposable this.toDispose = []; this.toDispose.push(this.configurationService.addListener2(ConfigurationServiceEventTypes.UPDATED, e => this.onConfiguration(e.config.git))); - configurationService.loadConfiguration('git').done(c => this.onConfiguration(c)); + this.onConfiguration(configurationService.getConfiguration('git')); } public get state(): git.AutoFetcherState { diff --git a/src/vs/workbench/parts/git/electron-browser/electronGitService.ts b/src/vs/workbench/parts/git/electron-browser/electronGitService.ts index 3409a32eaee144c7634526f64f807f207d4aba6b..9b873e154cb20154eb428ef5f992b7b5f2f726a4 100644 --- a/src/vs/workbench/parts/git/electron-browser/electronGitService.ts +++ b/src/vs/workbench/parts/git/electron-browser/electronGitService.ts @@ -144,7 +144,7 @@ function createNativeRawGitService(workspaceRoot: string, path: string, defaultE class ElectronRawGitService extends DelayedRawGitService { constructor(workspaceRoot: string, @IConfigurationService configurationService: IConfigurationService) { - super(configurationService.loadConfiguration().then(conf => { + super(TPromise.as(configurationService.getConfiguration()).then(conf => { var enabled = conf.git ? conf.git.enabled : true; if (!enabled) { diff --git a/src/vs/workbench/parts/markdown/browser/markdownExtension.ts b/src/vs/workbench/parts/markdown/browser/markdownExtension.ts index ecdc192aeb4242a90794b73454c66298937100b6..ea4ad919303a308489a49f3e7814e64126204926 100644 --- a/src/vs/workbench/parts/markdown/browser/markdownExtension.ts +++ b/src/vs/workbench/parts/markdown/browser/markdownExtension.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import errors = require('vs/base/common/errors'); import types = require('vs/base/common/types'); import URI from 'vs/base/common/uri'; import {EventType} from 'vs/base/common/events'; @@ -72,9 +71,7 @@ export class MarkdownFileTracker implements IWorkbenchContribution { this.editorInputChangeListener = this.eventService.addListener(WorkbenchEventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => this.onEditorInputChanged(e)); // initially read the config for CSS styles in preview - this.configurationService.loadConfiguration().done((config) => { - this.readMarkdownConfiguration(config); - }, errors.onUnexpectedError); + this.readMarkdownConfiguration(this.configurationService.getConfiguration()); // listen to theme changes this.themeChangeListener = this.storageService.addListener(StorageEventType.STORAGE, (e: StorageEvent) => { diff --git a/src/vs/workbench/parts/search/browser/openFileHandler.ts b/src/vs/workbench/parts/search/browser/openFileHandler.ts index e8d2bd50bd92a6ee08e2676d157f45640791bc69..6a3565508ef34dcefa01173b32e34a9d46ab0434 100644 --- a/src/vs/workbench/parts/search/browser/openFileHandler.ts +++ b/src/vs/workbench/parts/search/browser/openFileHandler.ts @@ -122,7 +122,7 @@ export class OpenFileHandler extends QuickOpenHandler { filePattern: searchValue }; - return this.queryBuilder.file(query).then((query) => this.searchService.search(query)).then((complete) => { + return this.searchService.search(this.queryBuilder.file(query)).then((complete) => { let results: QuickOpenEntry[] = []; for (let i = 0; i < complete.results.length; i++) { let fileMatch = complete.results[i]; diff --git a/src/vs/workbench/parts/search/browser/searchViewlet.ts b/src/vs/workbench/parts/search/browser/searchViewlet.ts index 72c6cd6d48e1c5b1ebbac34143d9cd7a85de5aa0..007e58cce4ee4b486b65f939dcc8ebbedbab6adc 100644 --- a/src/vs/workbench/parts/search/browser/searchViewlet.ts +++ b/src/vs/workbench/parts/search/browser/searchViewlet.ts @@ -909,9 +909,7 @@ export class SearchViewlet extends Viewlet { this.toggleFileTypes(true, true, true); } - this.configurationService.loadConfiguration().then((configuration) => { - this.updateGlobalPatternExclusions(configuration); - }).done(null, errors.onUnexpectedError); + this.updateGlobalPatternExclusions(this.configurationService.getConfiguration()); return TPromise.as(null); } @@ -1148,8 +1146,7 @@ export class SearchViewlet extends Viewlet { maxResults: SearchViewlet.MAX_TEXT_RESULTS, }; - this.queryBuilder.text(content, options) - .then(query => this.onQueryTriggered(query, patternExcludes, patternIncludes), errors.onUnexpectedError); + this.onQueryTriggered(this.queryBuilder.text(content, options), patternExcludes, patternIncludes); if (!preserveFocus) { this.findInput.focus(); // focus back to input field diff --git a/src/vs/workbench/parts/search/common/searchQuery.ts b/src/vs/workbench/parts/search/common/searchQuery.ts index ae2a715cc70e4b6185069900d9eb8e7b37059b6b..39418133ff72d010accbcb8ab3f01c6b6412e016 100644 --- a/src/vs/workbench/parts/search/common/searchQuery.ts +++ b/src/vs/workbench/parts/search/common/searchQuery.ts @@ -6,7 +6,6 @@ import glob = require('vs/base/common/glob'); import objects = require('vs/base/common/objects'); -import {TPromise} from 'vs/base/common/winjs.base'; import search = require('vs/platform/search/common/search'); import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; @@ -34,34 +33,34 @@ export class QueryBuilder { constructor( @IConfigurationService private configurationService: IConfigurationService) { } - public text(contentPattern: search.IPatternInfo, options?: search.IQueryOptions): TPromise { + public text(contentPattern: search.IPatternInfo, options?: search.IQueryOptions): search.ISearchQuery { return this.query(search.QueryType.Text, contentPattern, options); } - public file(options?: search.IQueryOptions): TPromise { + public file(options?: search.IQueryOptions): search.ISearchQuery { return this.query(search.QueryType.File, null, options); } - private query(type: search.QueryType, contentPattern: search.IPatternInfo, options: search.IQueryOptions = {}): TPromise { - return this.configurationService.loadConfiguration().then((configuration: search.ISearchConfiguration) => { - let excludePattern = getExcludes(configuration); - if (!options.excludePattern) { - options.excludePattern = excludePattern; - } else { - objects.mixin(options.excludePattern, excludePattern, false /* no overwrite */); - } + private query(type: search.QueryType, contentPattern: search.IPatternInfo, options: search.IQueryOptions = {}): search.ISearchQuery { + const configuration = this.configurationService.getConfiguration(); - return { - type: type, - folderResources: options.folderResources, - extraFileResources: options.extraFileResources, - filePattern: options.filePattern, - excludePattern: options.excludePattern, - includePattern: options.includePattern, - maxResults: options.maxResults, - fileEncoding: options.fileEncoding, - contentPattern: contentPattern - }; - }); + let excludePattern = getExcludes(configuration); + if (!options.excludePattern) { + options.excludePattern = excludePattern; + } else { + objects.mixin(options.excludePattern, excludePattern, false /* no overwrite */); + } + + return { + type: type, + folderResources: options.folderResources, + extraFileResources: options.extraFileResources, + filePattern: options.filePattern, + excludePattern: options.excludePattern, + includePattern: options.includePattern, + maxResults: options.maxResults, + fileEncoding: options.fileEncoding, + contentPattern: contentPattern + }; } } \ No newline at end of file diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index 6664249d08b5441e31725013c72a39aa3f412ee2..b3fb59a59fc75a2542b420c8893d5660ea2b76be 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -533,7 +533,7 @@ class TaskService extends EventEmitter implements ITaskService { if (!this._taskSystemPromise) { let variables = new SystemVariables(this.editorService, this.contextService); let clearOutput = true; - this._taskSystemPromise = this.configurationService.loadConfiguration('tasks').then((config: TaskConfiguration) => { + this._taskSystemPromise = TPromise.as(this.configurationService.getConfiguration('tasks')).then((config: TaskConfiguration) => { let parseErrors: string[] = config ? (config).$parseErrors : null; if (parseErrors) { let isAffected = false; diff --git a/src/vs/workbench/services/configuration/node/configurationService.ts b/src/vs/workbench/services/configuration/node/configurationService.ts index ed5be5c7040d70174c2433c3997cf022deb839d9..30d2229072e8830461d39e7b456d94e424c9528e 100644 --- a/src/vs/workbench/services/configuration/node/configurationService.ts +++ b/src/vs/workbench/services/configuration/node/configurationService.ts @@ -24,14 +24,28 @@ import fs = require('fs'); export class ConfigurationService extends CommonConfigurationService { public serviceId = IConfigurationService; + protected contextService: IWorkspaceContextService; private toDispose: Function; constructor(contextService: IWorkspaceContextService, eventService: IEventService) { super(contextService, eventService); + this.registerListeners(); } + protected registerListeners(): void { + super.registerListeners(); + + this.toDispose = this.eventService.addListener(EventType.WORKBENCH_OPTIONS_CHANGED, (e) => this.onOptionsChanged(e)); + } + + private onOptionsChanged(e: OptionsChangeEvent): void { + if (e.key === 'globalSettings') { + this.handleConfigurationChange(); + } + } + protected resolveContents(resources: uri[]): TPromise { let contents: IContent[] = []; @@ -88,16 +102,6 @@ export class ConfigurationService extends CommonConfigurationService { }); } - private registerListeners(): void { - this.toDispose = this.eventService.addListener(EventType.WORKBENCH_OPTIONS_CHANGED, (e) => this.onOptionsChanged(e)); - } - - private onOptionsChanged(e: OptionsChangeEvent): void { - if (e.key === 'globalSettings') { - this.reloadConfiguration(); - } - } - protected loadWorkspaceConfiguration(section?: string): TPromise<{ [relativeWorkspacePath: string]: IConfigFile }> { // Return early if we don't have a workspace @@ -105,25 +109,26 @@ export class ConfigurationService extends CommonConfigurationService { return TPromise.as({}); } - // Migrate as needed (.settings => .vscode) return super.loadWorkspaceConfiguration(section); } - protected loadGlobalConfiguration(): TPromise<{ contents: any; parseErrors?: string[]; }> { - return super.loadGlobalConfiguration().then((defaults) => { - let globalSettings = this.contextService.getOptions().globalSettings; - return { - contents: objects.mixin( - objects.clone(defaults.contents), // target: default values (but don't modify!) - globalSettings.settings, // source: global configured values - true // overwrite - ), - parseErrors: globalSettings.settingsParseErrors - }; - }); + protected loadGlobalConfiguration(): { contents: any; parseErrors?: string[]; } { + const defaults = super.loadGlobalConfiguration(); + const globalSettings = this.contextService.getOptions().globalSettings; + + return { + contents: objects.mixin( + objects.clone(defaults.contents), // target: default values (but don't modify!) + globalSettings.settings, // source: global configured values + true // overwrite + ), + parseErrors: globalSettings.settingsParseErrors + }; } public dispose(): void { + super.dispose(); + this.toDispose(); } } \ No newline at end of file diff --git a/src/vs/workbench/services/files/electron-browser/fileService.ts b/src/vs/workbench/services/files/electron-browser/fileService.ts index b20bc23f6a9920eccc0a5cae6426192a37937935..32e7e7aaf807d2e00ff308780942c01fe3896769 100644 --- a/src/vs/workbench/services/files/electron-browser/fileService.ts +++ b/src/vs/workbench/services/files/electron-browser/fileService.ts @@ -12,7 +12,7 @@ import errors = require('vs/base/common/errors'); import strings = require('vs/base/common/strings'); import uri from 'vs/base/common/uri'; import timer = require('vs/base/common/timer'); -import files = require('vs/platform/files/common/files'); +import {IFileService, IFilesConfiguration, IResolveFileOptions, IFileStat, IContent, IImportResult, IResolveContentOptions, IUpdateContentOptions} from 'vs/platform/files/common/files'; import {FileService as NodeFileService, IFileServiceOptions, IEncodingOverride} from 'vs/workbench/services/files/node/fileService'; import {IConfigurationService, IConfigurationServiceEvent, ConfigurationServiceEventTypes} from 'vs/platform/configuration/common/configuration'; import {IEventService} from 'vs/platform/event/common/event'; @@ -20,10 +20,11 @@ import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; import {shell} from 'electron'; -export class FileService implements files.IFileService { - public serviceId = files.IFileService; +export class FileService implements IFileService { - private raw: TPromise; + public serviceId = IFileService; + + private raw: IFileService; private configurationChangeListenerUnbind: () => void; @@ -32,40 +33,35 @@ export class FileService implements files.IFileService { private eventService: IEventService, private contextService: IWorkspaceContextService ) { + const configuration = this.configurationService.getConfiguration(); - // Init raw implementation - this.raw = this.configurationService.loadConfiguration().then((configuration: files.IFilesConfiguration) => { - - // adjust encodings (TODO@Ben knowledge on settings location ('.vscode') is hardcoded) - let encodingOverride: IEncodingOverride[] = []; - encodingOverride.push({ resource: uri.file(this.contextService.getConfiguration().env.appSettingsHome), encoding: encoding.UTF8 }); - if (this.contextService.getWorkspace()) { - encodingOverride.push({ resource: uri.file(paths.join(this.contextService.getWorkspace().resource.fsPath, '.vscode')), encoding: encoding.UTF8 }); - } - - let watcherIgnoredPatterns:string[] = []; - if (configuration.files && configuration.files.watcherExclude) { - watcherIgnoredPatterns = Object.keys(configuration.files.watcherExclude).filter(k => !!configuration.files.watcherExclude[k]); - } - - // build config - let fileServiceConfig: IFileServiceOptions = { - errorLogger: (msg: string) => errors.onUnexpectedError(msg), - encoding: configuration.files && configuration.files.encoding, - encodingOverride: encodingOverride, - watcherIgnoredPatterns: watcherIgnoredPatterns, - verboseLogging: this.contextService.getConfiguration().env.verboseLogging - }; + // adjust encodings (TODO@Ben knowledge on settings location ('.vscode') is hardcoded) + let encodingOverride: IEncodingOverride[] = []; + encodingOverride.push({ resource: uri.file(this.contextService.getConfiguration().env.appSettingsHome), encoding: encoding.UTF8 }); + if (this.contextService.getWorkspace()) { + encodingOverride.push({ resource: uri.file(paths.join(this.contextService.getWorkspace().resource.fsPath, '.vscode')), encoding: encoding.UTF8 }); + } - // create service - let workspace = this.contextService.getWorkspace(); - return new NodeFileService(workspace ? workspace.resource.fsPath : void 0, this.eventService, fileServiceConfig); - }); + let watcherIgnoredPatterns: string[] = []; + if (configuration.files && configuration.files.watcherExclude) { + watcherIgnoredPatterns = Object.keys(configuration.files.watcherExclude).filter(k => !!configuration.files.watcherExclude[k]); + } + + // build config + let fileServiceConfig: IFileServiceOptions = { + errorLogger: (msg: string) => errors.onUnexpectedError(msg), + encoding: configuration.files && configuration.files.encoding, + encodingOverride: encodingOverride, + watcherIgnoredPatterns: watcherIgnoredPatterns, + verboseLogging: this.contextService.getConfiguration().env.verboseLogging + }; + + // create service + let workspace = this.contextService.getWorkspace(); + this.raw = new NodeFileService(workspace ? workspace.resource.fsPath : void 0, this.eventService, fileServiceConfig); // Listeners - this.raw.done((raw) => { - this.registerListeners(); - }, errors.onUnexpectedError); + this.registerListeners(); } private registerListeners(): void { @@ -74,85 +70,65 @@ export class FileService implements files.IFileService { this.configurationChangeListenerUnbind = this.configurationService.addListener(ConfigurationServiceEventTypes.UPDATED, (e: IConfigurationServiceEvent) => this.onConfigurationChange(e.config)); } - private onConfigurationChange(configuration: files.IFilesConfiguration): void { + private onConfigurationChange(configuration: IFilesConfiguration): void { this.updateOptions(configuration.files); } public updateOptions(options: any): void { - this.raw.done((raw) => { - raw.updateOptions(options); - }, errors.onUnexpectedError); + this.raw.updateOptions(options); } - public resolveFile(resource: uri, options?: files.IResolveFileOptions): TPromise { - return this.raw.then((raw) => { - return raw.resolveFile(resource, options); - }); + public resolveFile(resource: uri, options?: IResolveFileOptions): TPromise { + return this.raw.resolveFile(resource, options); } - public resolveContent(resource: uri, options?: files.IResolveContentOptions): TPromise { + public resolveContent(resource: uri, options?: IResolveContentOptions): TPromise { let contentId = resource.toString(); let timerEvent = timer.start(timer.Topic.WORKBENCH, strings.format('Load {0}', contentId)); - return this.raw.then((raw) => { - return raw.resolveContent(resource, options).then((result) => { - timerEvent.stop(); + return this.raw.resolveContent(resource, options).then((result) => { + timerEvent.stop(); - return result; - }); + return result; }); } - public resolveContents(resources: uri[]): TPromise { - return this.raw.then((raw) => { - return raw.resolveContents(resources); - }); + public resolveContents(resources: uri[]): TPromise { + return this.raw.resolveContents(resources); } - public updateContent(resource: uri, value: string, options?: files.IUpdateContentOptions): TPromise { + public updateContent(resource: uri, value: string, options?: IUpdateContentOptions): TPromise { let timerEvent = timer.start(timer.Topic.WORKBENCH, strings.format('Save {0}', resource.toString())); - return this.raw.then((raw) => { - return raw.updateContent(resource, value, options).then((result) => { - timerEvent.stop(); + return this.raw.updateContent(resource, value, options).then((result) => { + timerEvent.stop(); - return result; - }, (error) => { - timerEvent.stop(); + return result; + }, (error) => { + timerEvent.stop(); - return TPromise.wrapError(error); - }); + return TPromise.wrapError(error); }); } - public moveFile(source: uri, target: uri, overwrite?: boolean): TPromise { - return this.raw.then((raw) => { - return raw.moveFile(source, target, overwrite); - }); + public moveFile(source: uri, target: uri, overwrite?: boolean): TPromise { + return this.raw.moveFile(source, target, overwrite); } - public copyFile(source: uri, target: uri, overwrite?: boolean): TPromise { - return this.raw.then((raw) => { - return raw.copyFile(source, target, overwrite); - }); + public copyFile(source: uri, target: uri, overwrite?: boolean): TPromise { + return this.raw.copyFile(source, target, overwrite); } - public createFile(resource: uri, content?: string): TPromise { - return this.raw.then((raw) => { - return raw.createFile(resource, content); - }); + public createFile(resource: uri, content?: string): TPromise { + return this.raw.createFile(resource, content); } - public createFolder(resource: uri): TPromise { - return this.raw.then((raw) => { - return raw.createFolder(resource); - }); + public createFolder(resource: uri): TPromise { + return this.raw.createFolder(resource); } - public rename(resource: uri, newName: string): TPromise { - return this.raw.then((raw) => { - return raw.rename(resource, newName); - }); + public rename(resource: uri, newName: string): TPromise { + return this.raw.rename(resource, newName); } public del(resource: uri, useTrash?: boolean): TPromise { @@ -160,9 +136,7 @@ export class FileService implements files.IFileService { return this.doMoveItemToTrash(resource); } - return this.raw.then((raw) => { - return raw.del(resource); - }); + return this.raw.del(resource); } private doMoveItemToTrash(resource: uri): TPromise { @@ -181,14 +155,12 @@ export class FileService implements files.IFileService { return TPromise.as(null); } - public importFile(source: uri, targetFolder: uri): TPromise { - return this.raw.then((raw) => { - return raw.importFile(source, targetFolder).then((result) => { - return { - isNew: result && result.isNew, - stat: result && result.stat - }; - }); + public importFile(source: uri, targetFolder: uri): TPromise { + return this.raw.importFile(source, targetFolder).then((result) => { + return { + isNew: result && result.isNew, + stat: result && result.stat + }; }); } @@ -206,17 +178,13 @@ export class FileService implements files.IFileService { return; } - this.raw.then((raw) => { - raw.watchFileChanges(resource); - }); + this.raw.watchFileChanges(resource); } public unwatchFileChanges(resource: uri): void; public unwatchFileChanges(path: string): void; public unwatchFileChanges(arg1: any): void { - this.raw.then((raw) => { - raw.unwatchFileChanges(arg1); - }); + this.raw.unwatchFileChanges(arg1); } public dispose(): void { @@ -228,6 +196,6 @@ export class FileService implements files.IFileService { } // Dispose service - this.raw.done((raw) => raw.dispose()); + this.raw.dispose(); } } \ No newline at end of file diff --git a/src/vs/workbench/services/request/node/requestService.ts b/src/vs/workbench/services/request/node/requestService.ts index 882dfaba9004b08ce6002db392500a99ac1e573b..6e3614495a7253ba90ff595acfa7854edb3452bf 100644 --- a/src/vs/workbench/services/request/node/requestService.ts +++ b/src/vs/workbench/services/request/node/requestService.ts @@ -51,10 +51,10 @@ export class RequestService extends BaseRequestService { private _rawHttpServicePromise: TPromise; private get rawHttpServicePromise(): TPromise { if (!this._rawHttpServicePromise) { - this._rawHttpServicePromise = this.configurationService.loadConfiguration().then((configuration: any) => { - rawHttpService.configure(configuration.http && configuration.http.proxy, configuration.http.proxyStrictSSL); - return rawHttpService; - }); + const configuration = this.configurationService.getConfiguration(); + rawHttpService.configure(configuration.http && configuration.http.proxy, configuration.http.proxyStrictSSL); + + return TPromise.as(rawHttpService); } return this._rawHttpServicePromise; diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index 945614849567a6d89b9b92e2e8e61568a678b670..1838c125a2df65333201070936ad5d3feb4b0969 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -34,71 +34,70 @@ export class SearchService implements ISearchService { } public search(query: ISearchQuery): PPromise { - return this.configurationService.loadConfiguration().then((configuration: ISearchConfiguration) => { + const configuration = this.configurationService.getConfiguration(); - // Configuration: Encoding - if (!query.fileEncoding) { - let fileEncoding = configuration && configuration.files && configuration.files.encoding; - query.fileEncoding = fileEncoding; - } + // Configuration: Encoding + if (!query.fileEncoding) { + let fileEncoding = configuration && configuration.files && configuration.files.encoding; + query.fileEncoding = fileEncoding; + } - // Configuration: File Excludes - let fileExcludes = configuration && configuration.files && configuration.files.exclude; - if (fileExcludes) { - if (!query.excludePattern) { - query.excludePattern = fileExcludes; - } else { - objects.mixin(query.excludePattern, fileExcludes, false /* no overwrite */); - } + // Configuration: File Excludes + let fileExcludes = configuration && configuration.files && configuration.files.exclude; + if (fileExcludes) { + if (!query.excludePattern) { + query.excludePattern = fileExcludes; + } else { + objects.mixin(query.excludePattern, fileExcludes, false /* no overwrite */); } + } - let rawSearchQuery: PPromise; - return new PPromise((onComplete, onError, onProgress) => { + let rawSearchQuery: PPromise; + return new PPromise((onComplete, onError, onProgress) => { - // Get local results from dirty/untitled - let localResultsFlushed = false; - let localResults = this.getLocalResults(query); + // Get local results from dirty/untitled + let localResultsFlushed = false; + let localResults = this.getLocalResults(query); - let flushLocalResultsOnce = function() { - if (!localResultsFlushed) { - localResultsFlushed = true; - Object.keys(localResults).map((key) => localResults[key]).filter((res) => !!res).forEach(onProgress); - } - }; - - // Delegate to parent for real file results - rawSearchQuery = this.diskSearch.search(query).then( - - // on Complete - (complete) => { - flushLocalResultsOnce(); - onComplete({ results: complete.results.filter((match) => typeof localResults[match.resource.toString()] === 'undefined'), limitHit: complete.limitHit }); // dont override local results - }, - - // on Error - (error) => { - flushLocalResultsOnce(); - onError(error); - }, - - // on Progress - (progress) => { - flushLocalResultsOnce(); - - // Match - if (progress.resource) { - if (typeof localResults[progress.resource.toString()] === 'undefined') { // don't override local results - onProgress(progress); - } + let flushLocalResultsOnce = function () { + if (!localResultsFlushed) { + localResultsFlushed = true; + Object.keys(localResults).map((key) => localResults[key]).filter((res) => !!res).forEach(onProgress); + } + }; + + // Delegate to parent for real file results + rawSearchQuery = this.diskSearch.search(query).then( + + // on Complete + (complete) => { + flushLocalResultsOnce(); + onComplete({ results: complete.results.filter((match) => typeof localResults[match.resource.toString()] === 'undefined'), limitHit: complete.limitHit }); // dont override local results + }, + + // on Error + (error) => { + flushLocalResultsOnce(); + onError(error); + }, + + // on Progress + (progress) => { + flushLocalResultsOnce(); + + // Match + if (progress.resource) { + if (typeof localResults[progress.resource.toString()] === 'undefined') { // don't override local results + onProgress(progress); } + } - // Progress - else { - onProgress(progress); - } - }); - }, () => rawSearchQuery && rawSearchQuery.cancel()); - }); + // Progress + else { + onProgress(progress); + } + }); + }, () => rawSearchQuery && rawSearchQuery.cancel()); } private getLocalResults(query: ISearchQuery): { [resourcePath: string]: IFileMatch; } { diff --git a/src/vs/workbench/test/browser/servicesTestUtils.ts b/src/vs/workbench/test/browser/servicesTestUtils.ts index 2643e545beff3e4a8e218966a5fcf5f3f33c5cce..7fa1406c9b819be212fbc09ff98ecdb70748ed73 100644 --- a/src/vs/workbench/test/browser/servicesTestUtils.ts +++ b/src/vs/workbench/test/browser/servicesTestUtils.ts @@ -498,8 +498,8 @@ export const TestFileService = { export class TestConfigurationService extends EventEmitter.EventEmitter implements IConfigurationService { public serviceId = IConfigurationService; - public loadConfiguration(section?:string):TPromise { - return TPromise.as({}); + public getConfiguration(): any { + return {}; } public hasWorkspaceConfiguration():boolean {