diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index fb7b82cdda6..aef67f0ec99 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import * as path from 'vs/base/common/path'; import { originalFSPath, joinPath } from 'vs/base/common/resources'; -import { Barrier } from 'vs/base/common/async'; +import { Barrier, timeout } from 'vs/base/common/async'; import { dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { TernarySearchTree } from 'vs/base/common/map'; import { URI } from 'vs/base/common/uri'; @@ -426,41 +426,44 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio // -- eager activation - // Handle "eager" activation extensions - private _handleEagerExtensions(): Promise { - this._activateByEvent('*', true).then(undefined, (err) => { + private _activateOneStartupFinished(desc: IExtensionDescription, activationEvent: string): void { + this._activateById(desc.identifier, { + startup: false, + extensionId: desc.identifier, + activationEvent: activationEvent + }).then(undefined, (err) => { this._logService.error(err); }); + } + private _activateAllStartupFinished(): void { for (const desc of this._registry.getAllExtensionDescriptions()) { if (desc.activationEvents) { for (const activationEvent of desc.activationEvents) { - if (/^onStartup:/.test(activationEvent)) { - const strTime = activationEvent.substr('onStartup:'.length); - const time = parseInt(strTime, 10); - if (!isNaN(time)) { - this._activateDelayed(desc, activationEvent, time); - } + if (activationEvent === 'onStartupFinished') { + this._activateOneStartupFinished(desc, activationEvent); } } } } + } + + // Handle "eager" activation extensions + private _handleEagerExtensions(): Promise { + const starActivation = this._activateByEvent('*', true).then(undefined, (err) => { + this._logService.error(err); + }); this._disposables.add(this._extHostWorkspace.onDidChangeWorkspace((e) => this._handleWorkspaceContainsEagerExtensions(e.added))); const folders = this._extHostWorkspace.workspace ? this._extHostWorkspace.workspace.folders : []; - return this._handleWorkspaceContainsEagerExtensions(folders); - } + const workspaceContainsActivation = this._handleWorkspaceContainsEagerExtensions(folders); + const eagerExtensionsActivation = Promise.all([starActivation, workspaceContainsActivation]).then(() => { }); - private _activateDelayed(desc: IExtensionDescription, activationEvent: string, delayMs: number): void { - setTimeout(() => { - this._activateById(desc.identifier, { - startup: true, - extensionId: desc.identifier, - activationEvent: activationEvent - }).then(undefined, (err) => { - this._logService.error(err); - }); - }, delayMs); + Promise.race([eagerExtensionsActivation, timeout(10000)]).then(() => { + this._activateAllStartupFinished(); + }); + + return eagerExtensionsActivation; } private _handleWorkspaceContainsEagerExtensions(folders: ReadonlyArray): Promise { diff --git a/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts b/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts index edc85904b4a..8a34e72ad0b 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts @@ -372,9 +372,8 @@ export class RuntimeExtensionsEditor extends BaseEditor { '{0} will be a glob pattern' ] }, "Activated by {1} because searching for {0} took too long", glob, activationId); - } else if (/^onStartup:/.test(activationEvent)) { - const time = activationEvent.substr('onStartup:'.length); - title = nls.localize('startupActivation', "Activated by {0} with a delay of {1} ms on start-up", activationId, time); + } else if (activationEvent === 'onStartupFinished') { + title = nls.localize('startupFinishedActivation', "Activated by {0} after start-up finished", activationId); } else if (/^onLanguage:/.test(activationEvent)) { let language = activationEvent.substr('onLanguage:'.length); title = nls.localize('languageActivation', "Activated by {1} because you opened a {0} file", language, activationId); diff --git a/src/vs/workbench/services/extensions/common/extensionsRegistry.ts b/src/vs/workbench/services/extensions/common/extensionsRegistry.ts index 9896fc50223..166d02a14a1 100644 --- a/src/vs/workbench/services/extensions/common/extensionsRegistry.ts +++ b/src/vs/workbench/services/extensions/common/extensionsRegistry.ts @@ -270,9 +270,9 @@ export const schema: IJSONSchema = { body: 'workspaceContains:${4:filePattern}' }, { - label: 'onStartup', - description: nls.localize('vscode.extension.activationEvents.onStartup', 'An activation event emitted a certain amount of milliseconds after the start-up.'), - body: 'onStartup:${1:2000}' + label: 'onStartupFinished', + description: nls.localize('vscode.extension.activationEvents.onStartupFinished', 'An activation event emitted after the start-up finished (after all eager activated extensions have finished activating).'), + body: 'onStartupFinished' }, { label: 'onFileSystem', diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index 7312cf69713..d8b5ecf4f5a 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -324,7 +324,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten break; } - if (/^onStartup/.test(activationEvent)) { + if (activationEvent === 'onStartupFinished') { shouldActivate = true; shouldActivateReason = activationEvent; break;