diff --git a/src/vs/workbench/api/browser/mainThreadWorkspace.ts b/src/vs/workbench/api/browser/mainThreadWorkspace.ts index 13d352d9bd4..252fa8e426e 100644 --- a/src/vs/workbench/api/browser/mainThreadWorkspace.ts +++ b/src/vs/workbench/api/browser/mainThreadWorkspace.ts @@ -24,6 +24,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { withNullAsUndefined } from 'vs/base/common/types'; import { IFileService } from 'vs/platform/files/common/files'; import { IRequestService } from 'vs/platform/request/common/request'; +import { checkGlobFileExists } from 'vs/workbench/api/common/shared/workspaceContains'; @extHostNamedCustomer(MainContext.MainThreadWorkspace) export class MainThreadWorkspace implements MainThreadWorkspaceShape { @@ -189,25 +190,7 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { } $checkExists(folders: readonly UriComponents[], includes: string[], token: CancellationToken): Promise { - const queryBuilder = this._instantiationService.createInstance(QueryBuilder); - const query = queryBuilder.file(folders.map(folder => toWorkspaceFolder(URI.revive(folder))), { - _reason: 'checkExists', - includePattern: includes.join(', '), - expandPatterns: true, - exists: true - }); - - return this._searchService.fileSearch(query, token).then( - result => { - return !!result.limitHit; - }, - err => { - if (!isPromiseCanceledError(err)) { - return Promise.reject(err); - } - - return false; - }); + return this._instantiationService.invokeFunction((accessor) => checkGlobFileExists(accessor, folders, includes, token)); } // --- save & edit resources --- diff --git a/src/vs/workbench/api/common/shared/workspaceContains.ts b/src/vs/workbench/api/common/shared/workspaceContains.ts index 8a641e241dd..7f883983ea7 100644 --- a/src/vs/workbench/api/common/shared/workspaceContains.ts +++ b/src/vs/workbench/api/common/shared/workspaceContains.ts @@ -8,6 +8,10 @@ import { URI, UriComponents } from 'vs/base/common/uri'; import { CancellationTokenSource, CancellationToken } from 'vs/base/common/cancellation'; import * as errors from 'vs/base/common/errors'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { QueryBuilder } from 'vs/workbench/contrib/search/common/queryBuilder'; +import { ISearchService } from 'vs/workbench/services/search/common/search'; +import { toWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; const WORKSPACE_CONTAINS_TIMEOUT = 7000; @@ -103,3 +107,32 @@ async function _activateIfGlobPatterns(host: IExtensionActivationHost, extension activate(`workspaceContains:${globPatterns.join(',')}`); } } + +export function checkGlobFileExists( + accessor: ServicesAccessor, + folders: readonly UriComponents[], + includes: string[], + token: CancellationToken, +): Promise { + const instantiationService = accessor.get(IInstantiationService); + const searchService = accessor.get(ISearchService); + const queryBuilder = instantiationService.createInstance(QueryBuilder); + const query = queryBuilder.file(folders.map(folder => toWorkspaceFolder(URI.revive(folder))), { + _reason: 'checkExists', + includePattern: includes.join(', '), + expandPatterns: true, + exists: true + }); + + return searchService.fileSearch(query, token).then( + result => { + return !!result.limitHit; + }, + err => { + if (!errors.isPromiseCanceledError(err)) { + return Promise.reject(err); + } + + return false; + }); +} diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index b149586e303..1438fdeabd4 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -41,6 +41,9 @@ import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/wor import { getRemoteName } from 'vs/platform/remote/common/remoteHosts'; import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; import { WebWorkerExtensionHost } from 'vs/workbench/services/extensions/browser/webWorkerExtensionHost'; +import { IExtensionActivationHost as IWorkspaceContainsActivationHost, checkGlobFileExists, checkActivateWorkspaceContainsExtension } from 'vs/workbench/api/common/shared/workspaceContains'; +import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { exists } from 'vs/base/node/pfs'; class DeltaExtensionsQueueItem { constructor( @@ -75,6 +78,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten @IHostService private readonly _hostService: IHostService, @IRemoteExplorerService private readonly _remoteExplorerService: IRemoteExplorerService, @IExtensionGalleryService private readonly _extensionGalleryService: IExtensionGalleryService, + @IWorkspaceContextService private readonly _contextService: IWorkspaceContextService, ) { super( instantiationService, @@ -308,6 +312,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten let shouldActivate = false; let shouldActivateReason: string | null = null; + let hasWorkspaceContains = false; if (Array.isArray(extensionDescription.activationEvents)) { for (let activationEvent of extensionDescription.activationEvents) { // TODO@joao: there's no easy way to contribute this @@ -329,10 +334,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten } if (/^workspaceContains/.test(activationEvent)) { - // do not trigger a search, just activate in this case... - shouldActivate = true; - shouldActivateReason = activationEvent; - break; + hasWorkspaceContains = true; } if (activationEvent === 'onStartupFinished') { @@ -347,6 +349,24 @@ export class ExtensionService extends AbstractExtensionService implements IExten await Promise.all( this._extensionHostManagers.map(extHostManager => extHostManager.activate(extensionDescription.identifier, { startup: false, extensionId: extensionDescription.identifier, activationEvent: shouldActivateReason! })) ).then(() => { }); + } else if (hasWorkspaceContains) { + const workspace = await this._contextService.getCompleteWorkspace(); + const forceUsingSearch = !!this._environmentService.configuration.remoteAuthority; + const host: IWorkspaceContainsActivationHost = { + folders: workspace.folders.map(folder => folder.uri), + forceUsingSearch: forceUsingSearch, + exists: (path) => exists(path), + checkExists: (folders, includes, token) => this._instantiationService.invokeFunction((accessor) => checkGlobFileExists(accessor, folders, includes, token)) + }; + + const result = await checkActivateWorkspaceContainsExtension(host, extensionDescription); + if (!result) { + return; + } + + await Promise.all( + this._extensionHostManagers.map(extHostManager => extHostManager.activate(extensionDescription.identifier, { startup: false, extensionId: extensionDescription.identifier, activationEvent: result.activationEvent })) + ).then(() => { }); } }