diff --git a/src/vs/workbench/api/common/extHostSearch.ts b/src/vs/workbench/api/common/extHostSearch.ts new file mode 100644 index 00000000000..efc6ca49825 --- /dev/null +++ b/src/vs/workbench/api/common/extHostSearch.ts @@ -0,0 +1,16 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IDisposable } from 'vs/base/common/lifecycle'; +import * as vscode from 'vscode'; +import { ExtHostSearchShape } from '../common/extHost.protocol'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export interface IExtHostSearch extends ExtHostSearchShape { + registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable; + registerFileSearchProvider(scheme: string, provider: vscode.FileSearchProvider): IDisposable; +} + +export const IExtHostSearch = createDecorator('IExtHostSearch'); diff --git a/src/vs/workbench/api/common/extHostUriTransformerService.ts b/src/vs/workbench/api/common/extHostUriTransformerService.ts new file mode 100644 index 00000000000..e9acd9bc5d6 --- /dev/null +++ b/src/vs/workbench/api/common/extHostUriTransformerService.ts @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IURITransformer } from 'vs/base/common/uriIpc'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { URI, UriComponents } from 'vs/base/common/uri'; + +export interface IURITransformerService extends IURITransformer { + _serviceBrand: any; +} + +export const IURITransformerService = createDecorator('IURITransformerService'); + +export class URITransformerService implements IURITransformerService { + _serviceBrand: any; + + transformIncoming: (uri: UriComponents) => UriComponents; + transformOutgoing: (uri: UriComponents) => UriComponents; + transformOutgoingURI: (uri: URI) => URI; + transformOutgoingScheme: (scheme: string) => string; + + constructor(delegate: IURITransformer | null) { + if (!delegate) { + this.transformIncoming = arg => arg; + this.transformOutgoing = arg => arg; + this.transformOutgoingURI = arg => arg; + this.transformOutgoingScheme = arg => arg; + } else { + this.transformIncoming = delegate.transformIncoming.bind(delegate); + this.transformOutgoing = delegate.transformOutgoing.bind(delegate); + this.transformOutgoingURI = delegate.transformOutgoingURI.bind(delegate); + this.transformOutgoingScheme = delegate.transformOutgoingScheme.bind(delegate); + } + } +} diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 8870ae9a0cf..52d3f877333 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -39,7 +39,6 @@ import { IExtHostOutputService } from 'vs/workbench/api/common/extHostOutput'; import { ExtHostProgress } from 'vs/workbench/api/common/extHostProgress'; import { ExtHostQuickOpen } from 'vs/workbench/api/common/extHostQuickOpen'; import { ExtHostSCM } from 'vs/workbench/api/common/extHostSCM'; -import { ExtHostSearch, registerEHSearchProviders } from 'vs/workbench/api/node/extHostSearch'; import { ExtHostStatusBar } from 'vs/workbench/api/common/extHostStatusBar'; import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; @@ -69,6 +68,7 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation import { IExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations'; import { IExtHostTask } from 'vs/workbench/api/common/extHostTask'; import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; +import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch'; export interface IExtensionApiFactory { (extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode; @@ -124,7 +124,7 @@ export function createApiFactory( const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, accessor.get(IExtHostDebugService)); const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService)); const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands, extHostDocuments)); - const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, new ExtHostSearch(rpcProtocol, uriTransformer, extHostLogService)); + const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, accessor.get(IExtHostSearch)); const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, accessor.get(IExtHostTask)); const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol)); rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService); @@ -140,8 +140,6 @@ export function createApiFactory( platform: process.platform }); - registerEHSearchProviders(extHostSearch, extHostLogService); - const cliServer = new CLIServer(extHostCommands); process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath; } diff --git a/src/vs/workbench/api/node/extHost.services.ts b/src/vs/workbench/api/node/extHost.services.ts index 4a8176170d7..434f8b170d8 100644 --- a/src/vs/workbench/api/node/extHost.services.ts +++ b/src/vs/workbench/api/node/extHost.services.ts @@ -17,6 +17,8 @@ import { IExtHostTask } from 'vs/workbench/api/common/extHostTask'; import { ExtHostTask } from 'vs/workbench/api/node/extHostTask'; import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService'; import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; +import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch'; +import { ExtHostSearch } from 'vs/workbench/api/node/extHostSearch'; // register singleton services registerSingleton(IExtHostOutputService, ExtHostOutputService2); @@ -28,3 +30,4 @@ registerSingleton(IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors); registerSingleton(IExtHostTerminalService, ExtHostTerminalService); registerSingleton(IExtHostTask, ExtHostTask); registerSingleton(IExtHostDebugService, ExtHostDebugService); +registerSingleton(IExtHostSearch, ExtHostSearch); diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index 5f6be2d3e60..ea1ee401e18 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -15,8 +15,10 @@ import { RipgrepSearchProvider } from 'vs/workbench/services/search/node/ripgrep import { OutputChannel } from 'vs/workbench/services/search/node/ripgrepSearchUtils'; import { TextSearchManager } from 'vs/workbench/services/search/node/textSearchManager'; import * as vscode from 'vscode'; -import { ExtHostSearchShape, IMainContext, MainContext, MainThreadSearchShape } from '../common/extHost.protocol'; -import { IURITransformer } from 'vs/base/common/uriIpc'; +import { ExtHostSearchShape, MainContext, MainThreadSearchShape } from '../common/extHost.protocol'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; export class ExtHostSearch implements ExtHostSearchShape { @@ -32,16 +34,30 @@ export class ExtHostSearch implements ExtHostSearchShape { private _fileSearchManager: FileSearchManager; - constructor(mainContext: IMainContext, private _uriTransformer: IURITransformer | null, private _logService: ILogService, private _pfs = pfs) { - this._proxy = mainContext.getProxy(MainContext.MainThreadSearch); + protected _pfs: typeof pfs = pfs; // allow extending for tests + + constructor( + @IExtHostRpcService extHostRpc: IExtHostRpcService, + @IExtHostInitDataService initData: IExtHostInitDataService, + @IURITransformerService private _uriTransformer: IURITransformerService, + @ILogService private _logService: ILogService, + ) { + this._proxy = extHostRpc.getProxy(MainContext.MainThreadSearch); this._fileSearchManager = new FileSearchManager(); + + if (initData.remote.isRemote && initData.remote.authority) { + this._registerEHSearchProviders(); + } + } + + private _registerEHSearchProviders(): void { + const outputChannel = new OutputChannel(this._logService); + this.registerTextSearchProvider('file', new RipgrepSearchProvider(outputChannel)); + this.registerInternalFileSearchProvider('file', new SearchService()); } private _transformScheme(scheme: string): string { - if (this._uriTransformer) { - return this._uriTransformer.transformOutgoingScheme(scheme); - } - return scheme; + return this._uriTransformer.transformOutgoingScheme(scheme); } registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable { @@ -148,12 +164,6 @@ export class ExtHostSearch implements ExtHostSearchShape { } } -export function registerEHSearchProviders(extHostSearch: ExtHostSearch, logService: ILogService): void { - const outputChannel = new OutputChannel(logService); - extHostSearch.registerTextSearchProvider('file', new RipgrepSearchProvider(outputChannel)); - extHostSearch.registerInternalFileSearchProvider('file', new SearchService()); -} - function reviveQuery(rawQuery: U): U extends IRawTextQuery ? ITextQuery : IFileQuery { return { ...rawQuery, // TODO diff --git a/src/vs/workbench/services/extensions/node/extensionHostMain.ts b/src/vs/workbench/services/extensions/node/extensionHostMain.ts index 89ce6ba8bc0..da8f9ff60aa 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostMain.ts @@ -21,6 +21,7 @@ import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitData import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IExtHostRpcService, ExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IURITransformerService, URITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; // we don't (yet) throw when extensions parse // uris that have no scheme @@ -72,6 +73,7 @@ export class ExtensionHostMain { services.set(IExtHostInitDataService, { _serviceBrand: undefined, ...initData }); services.set(IExtHostRpcService, new ExtHostRpcService(rpcProtocol)); services.set(ILogService, extHostLogService); + services.set(IURITransformerService, new URITransformerService(uriTransformer)); const instaService: IInstantiationService = new InstantiationService(services, true); diff --git a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts index 0d15201d893..8dff457b408 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts @@ -18,6 +18,9 @@ import { IFileMatch, IFileQuery, IPatternInfo, IRawFileMatch2, ISearchCompleteSt import { TestRPCProtocol } from 'vs/workbench/test/electron-browser/api/testRPCProtocol'; import * as vscode from 'vscode'; import { NullLogService } from 'vs/platform/log/common/log'; +import { URITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; +import { mock } from 'vs/workbench/test/electron-browser/api/mock'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; let rpcProtocol: TestRPCProtocol; let extHostSearch: ExtHostSearch; @@ -135,7 +138,17 @@ suite('ExtHostSearch', () => { rpcProtocol.set(MainContext.MainThreadSearch, mockMainThreadSearch); mockPFS = {}; - extHostSearch = new ExtHostSearch(rpcProtocol, null!, logService, mockPFS as any); + extHostSearch = new class extends ExtHostSearch { + constructor() { + super( + rpcProtocol, + new class extends mock() { remote = { isRemote: false, authority: undefined }; }, + new URITransformerService(null), + logService + ); + this._pfs = mockPFS as any; + } + }; }); teardown(() => {