From 52f98f46efd26903c9a35c4e03564e6548681bd8 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 17 Aug 2017 12:36:30 +0200 Subject: [PATCH] move find-file logic into fsprovider, wire things up end to end --- src/vs/vscode.proposed.d.ts | 7 +- .../electron-browser/mainThreadWorkspace.ts | 108 +++++++++--------- src/vs/workbench/api/node/extHost.protocol.ts | 7 +- src/vs/workbench/api/node/extHostWorkspace.ts | 13 +-- .../services/search/node/searchService.ts | 5 +- 5 files changed, 68 insertions(+), 72 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 354bb16a34e..393b2ddfe89 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -14,14 +14,13 @@ declare module 'vscode' { resolveContents(resource: Uri): string | Thenable; writeContents(resource: Uri, contents: string): void | Thenable; - } - export interface SearchProvider { - provideSearchResults(query: any, progress: Progress, token?: CancellationToken): Thenable; + // -- search + // todo@joh - extract into its own provider? + findFiles(query: string, progress: Progress, token?: CancellationToken): Thenable; } export namespace workspace { - export function registerFileSystemProvider(authority: string, provider: FileSystemProvider): Disposable; } diff --git a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts index 07dd4470313..9bbf81999ba 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts @@ -6,7 +6,7 @@ import { isPromiseCanceledError } from 'vs/base/common/errors'; import URI from 'vs/base/common/uri'; -import { ISearchService, QueryType, ISearchQuery } from 'vs/platform/search/common/search'; +import { ISearchService, QueryType, ISearchQuery, ISearchProgressItem, ISearchComplete } from 'vs/platform/search/common/search'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; @@ -16,8 +16,8 @@ import { TPromise, PPromise } from 'vs/base/common/winjs.base'; import { MainThreadWorkspaceShape, ExtHostWorkspaceShape, ExtHostContext, MainContext, IExtHostContext } from '../node/extHost.protocol'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { IFileService } from 'vs/platform/files/common/files'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { RemoteFileService, IRemoteFileSystemProvider } from 'vs/workbench/services/files/electron-browser/remoteFileService'; +import { IDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecycle'; +import { RemoteFileService } from 'vs/workbench/services/files/electron-browser/remoteFileService'; import { Emitter } from 'vs/base/common/event'; import { extHostNamedCustomer } from "vs/workbench/api/electron-browser/extHostCustomers"; @@ -101,53 +101,6 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { // --- save & edit resources --- - private readonly _searchProvider = new Map(); - private readonly _searchSession = new Map(); - private _searchSessionIdPool: number = 0; - - $registerSearchProvider(handle: number, type: number): void { - this._searchProvider.set(handle, this._searchService.registerSearchResultProvider({ - search: (query) => { - if (query.type !== type) { - return null; - } - const session = ++this._searchSessionIdPool; - return new PPromise((resolve, reject, progress) => { - this._searchSession.set(session, { resolve, reject, progress }); - this._proxy.$startSearch(handle, session, query); - }, () => { - this._proxy.$cancelSearch(handle, session); - }); - } - })); - } - - $unregisterSearchProvider(handle: number): void { - const registration = this._searchProvider.get(handle); - if (registration) { - registration.dispose(); - this._searchProvider.delete(handle); - } - } - - $updateSearchSession(session: number, data): void { - if (this._searchSession.has(session)) { - this._searchSession.get(session).progress(data); - } - } - - $finishSearchSession(session: number, err?: any): void { - if (this._searchSession.has(session)) { - const { resolve, reject } = this._searchSession.get(session); - this._searchSession.delete(session); - if (err) { - reject(err); - } else { - resolve(); - } - } - } - $saveAll(includeUntitled?: boolean): Thenable { return this._textFileService.saveAll(includeUntitled).then(result => { return result.results.every(each => each.success === true); @@ -171,7 +124,9 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { // --- EXPERIMENT: workspace provider - private _provider = new Map]>(); + private _idPool: number = 0; + private readonly _provider = new Map]>(); + private readonly _searchSessions = new Map void, reject: Function, progress: (item: ISearchProgressItem) => void, matches: URI[] }>(); $registerFileSystemProvider(handle: number, authority: string): void { if (!(this._fileService instanceof RemoteFileService)) { @@ -187,13 +142,60 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { return this._proxy.$storeFile(handle, resource, value); } }; - this._provider.set(handle, [provider, emitter]); - this._fileService.registerProvider(authority, provider); + const searchProvider = { + search: (query) => { + if (query.type !== QueryType.File) { + return undefined; + } + const session = ++this._idPool; + return new PPromise((resolve, reject, progress) => { + this._searchSessions.set(session, { resolve, reject, progress, matches: [] }); + this._proxy.$startSearch(handle, session, query.filePattern); + }, () => { + this._proxy.$cancelSearch(handle, session); + }); + } + }; + const registrations = combinedDisposable([ + this._fileService.registerProvider(authority, provider), + this._searchService.registerSearchResultProvider(searchProvider), + ]); + this._provider.set(handle, [registrations, emitter]); + } + + $unregisterFileSystemProvider(handle: number): void { + if (this._provider.has(handle)) { + dispose(this._provider.get(handle)[0]); + this._provider.delete(handle); + } } $onFileSystemChange(handle: number, resource: URI) { const [, emitter] = this._provider.get(handle); emitter.fire(resource); }; + + $updateSearchSession(session: number, data: URI): void { + if (this._searchSessions.has(session)) { + this._searchSessions.get(session).progress({ resource: data }); + this._searchSessions.get(session).matches.push(data); + } + } + + $finishSearchSession(session: number, err?: any): void { + if (this._searchSessions.has(session)) { + const { matches, resolve, reject } = this._searchSessions.get(session); + this._searchSessions.delete(session); + if (err) { + reject(err); + } else { + resolve({ + limitHit: false, + stats: undefined, + results: matches.map(resource => ({ resource })) + }); + } + } + } } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 908610522e7..ac5336fd3b5 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -278,11 +278,10 @@ export interface MainThreadWorkspaceShape extends IDisposable { $cancelSearch(requestId: number): Thenable; $saveAll(includeUntitled?: boolean): Thenable; $applyWorkspaceEdit(edits: IResourceEdit[]): TPromise; + $registerFileSystemProvider(handle: number, authority: string): void; + $unregisterFileSystemProvider(handle): void; $onFileSystemChange(handle: number, resource: URI): void; - - $registerSearchProvider(handle: number, type: number): void; - $unregisterSearchProvider(handle: number): void; $updateSearchSession(session: number, data): void; $finishSearchSession(session: number, err?: any): void; } @@ -426,7 +425,7 @@ export interface ExtHostWorkspaceShape { $resolveFile(handle: number, resource: URI): TPromise; $storeFile(handle: number, resource: URI, content: string): TPromise; - $startSearch(handle: number, session: number, query): void; + $startSearch(handle: number, session: number, query: string): void; $cancelSearch(handle: number, session: number): void; } diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index 7dcf5921b8b..56af8da9ce0 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -212,7 +212,6 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { private _handlePool = 0; private readonly _fsProvider = new Map(); - private readonly _searchProvider = new Map(); private readonly _searchSession = new Map(); registerFileSystemProvider(authority: string, provider: vscode.FileSystemProvider): vscode.Disposable { @@ -236,19 +235,13 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { return asWinJsPromise(token => provider.writeContents(resource, content)); } - registerSearchProvider(provider: vscode.SearchProvider): vscode.Disposable { - const handle = ++this._handlePool; - this._searchProvider.set(handle, provider); - return new Disposable(() => this._fsProvider.delete(handle)); - } - - $startSearch(handle: number, session: number, query): void { - const provider = this._searchProvider.get(handle); + $startSearch(handle: number, session: number, query: string): void { + const provider = this._fsProvider.get(handle); const source = new CancellationTokenSource(); const progress = new Progress(chunk => this._proxy.$updateSearchSession(session, chunk)); this._searchSession.set(session, source); - TPromise.wrap(provider.provideSearchResults(query, progress, source.token)).then(() => { + TPromise.wrap(provider.findFiles(query, progress, source.token)).then(() => { this._proxy.$finishSearchSession(session); }, err => { this._proxy.$finishSearchSession(session, err); diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index 8bb2b22035c..05e6a1885d4 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -104,7 +104,7 @@ export class SearchService implements ISearchService { // Allow caller to register progress callback process.nextTick(() => localResults.values().filter((res) => !!res).forEach(onProgress)); - const providerPromises = this.resultProvider.map(provider => provider.search(query).then(e => e, + const providerPromises = this.resultProvider.map(provider => TPromise.wrap(provider.search(query)).then(e => e, err => { // TODO@joh // single provider fail. fail all? @@ -134,6 +134,9 @@ export class SearchService implements ISearchService { // TODO@joh // sorting, disjunct results, individual stats/limit? for (const value of values) { + if (!value) { + continue; + } result.limitHit = value.limitHit || result.limitHit; for (const match of value.results) { if (!localResults.has(match.resource)) { -- GitLab