diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts index a350f5334e2..41305d076b2 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -520,6 +520,16 @@ suite('workspace-namespace', () => { assert.equal(vscode.workspace.asRelativePath(results[0].uri), '10linefile.ts'); }); + test('findTextInFiles, cancellation', async () => { + const results: vscode.TextSearchResult[] = []; + const cancellation = new vscode.CancellationTokenSource(); + cancellation.cancel(); + + await vscode.workspace.findTextInFiles({ pattern: 'foo' }, result => { + results.push(result); + }, cancellation.token); + }); + test('applyEdit', () => { return vscode.workspace.openTextDocument(vscode.Uri.parse('untitled:' + join(vscode.workspace.rootPath || '', './new2.txt'))).then(doc => { diff --git a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts index 8db9fa2331f..c43f1982a74 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts @@ -172,29 +172,29 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { const queryBuilder = this._instantiationService.createInstance(QueryBuilder); const query = queryBuilder.text(pattern, folders, options); - return new TPromise((resolve, reject) => { - const onProgress = (p: ISearchProgressItem) => { - if (p.lineMatches) { - this._proxy.$handleTextSearchResult(p, requestId); + const onProgress = (p: ISearchProgressItem) => { + if (p.lineMatches) { + this._proxy.$handleTextSearchResult(p, requestId); + } + }; + + const search = this._searchService.search(query, onProgress).then( + () => { + delete this._activeSearches[requestId]; + return null; + }, + err => { + delete this._activeSearches[requestId]; + if (!isPromiseCanceledError(err)) { + return TPromise.wrapError(err); } - }; - const search = this._searchService.search(query, onProgress).then( - () => { - delete this._activeSearches[requestId]; - resolve(null); - }, - err => { - delete this._activeSearches[requestId]; - if (!isPromiseCanceledError(err)) { - reject(TPromise.wrapError(err)); - } + return undefined; + }); - return undefined; - }); + this._activeSearches[requestId] = search; - this._activeSearches[requestId] = search; - }); + return search; } $cancelSearch(requestId: number): Thenable { diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index ae1f6739927..13de47ac058 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -395,7 +395,13 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { excludePattern: options.exclude && globPatternToString(options.exclude) }; + let isCanceled = false; + this._activeSearchCallbacks[requestId] = p => { + if (isCanceled) { + return; + } + p.lineMatches.forEach(lineMatch => { lineMatch.offsetAndLengths.forEach(offsetAndLength => { const range = new Range(lineMatch.lineNumber, offsetAndLength[0], lineMatch.lineNumber, offsetAndLength[0] + offsetAndLength[1]); @@ -409,7 +415,10 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape { }; if (token) { - token.onCancellationRequested(() => this._proxy.$cancelSearch(requestId)); + token.onCancellationRequested(() => { + isCanceled = true; + this._proxy.$cancelSearch(requestId); + }); } return this._proxy.$startTextSearch(query, queryOptions, requestId).then(