diff --git a/src/vs/workbench/api/electron-browser/mainThreadSearch.ts b/src/vs/workbench/api/electron-browser/mainThreadSearch.ts index 07836be7841..f5e2f7996e9 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSearch.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSearch.ts @@ -83,7 +83,7 @@ class SearchOperation { this.matches.set(match.resource.toString(), match); } - this.progress(this.matches.get(match.resource.toString())); + this.progress(match); } } diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index 3a59e002052..78a367e23ad 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -141,12 +141,13 @@ class TextSearchResultsCollector { // Collects TextSearchResults into IInternalFileMatches and collates using BatchedCollector. // This is efficient for ripgrep which sends results back one file at a time. It wouldn't be efficient for other search // providers that send results in random order. We could do this step afterwards instead. - if (this._currentFileMatch && (this._currentFolderIdx !== folderIdx || resources.isEqual(this._currentUri, data.uri))) { + if (this._currentFileMatch && (this._currentFolderIdx !== folderIdx || !resources.isEqual(this._currentUri, data.uri))) { this.pushToCollector(); this._currentFileMatch = null; } if (!this._currentFileMatch) { + this._currentFolderIdx = folderIdx; this._currentFileMatch = { resource: data.uri, matches: [] diff --git a/src/vs/workbench/parts/search/common/searchModel.ts b/src/vs/workbench/parts/search/common/searchModel.ts index 306759ab096..095a46e2f52 100644 --- a/src/vs/workbench/parts/search/common/searchModel.ts +++ b/src/vs/workbench/parts/search/common/searchModel.ts @@ -170,8 +170,8 @@ export class FileMatch extends Disposable { this.bindModel(model); this.updateMatchesForModel(); } else { - this.rawMatch.matches.forEach((rawLineMatch) => { - let match = new Match(this, rawLineMatch); + this.rawMatch.matches.forEach(rawMatch => { + let match = new Match(this, rawMatch); this.add(match); }); } @@ -410,20 +410,28 @@ export class FolderMatch extends Disposable { } public add(raw: IFileMatch[], silent: boolean): void { - const changed: FileMatch[] = []; + const added: FileMatch[] = []; + const updated: FileMatch[] = []; raw.forEach((rawFileMatch) => { if (this._fileMatches.has(rawFileMatch.resource)) { - this._fileMatches.get(rawFileMatch.resource).dispose(); + const existingFileMatch = this._fileMatches.get(rawFileMatch.resource); + rawFileMatch.matches.forEach(m => { + let match = new Match(existingFileMatch, m); + existingFileMatch.add(match); + }); + updated.push(existingFileMatch); + } else { + const fileMatch = this.instantiationService.createInstance(FileMatch, this._query.contentPattern, this._query.previewOptions, this._query.maxResults, this, rawFileMatch); + this.doAdd(fileMatch); + added.push(fileMatch); + const disposable = fileMatch.onChange(() => this.onFileChange(fileMatch)); + fileMatch.onDispose(() => disposable.dispose()); } - - const fileMatch = this.instantiationService.createInstance(FileMatch, this._query.contentPattern, this._query.previewOptions, this._query.maxResults, this, rawFileMatch); - this.doAdd(fileMatch); - changed.push(fileMatch); - const disposable = fileMatch.onChange(() => this.onFileChange(fileMatch)); - fileMatch.onDispose(() => disposable.dispose()); }); - if (!silent && changed.length) { - this._onChange.fire({ elements: changed, added: true }); + + const elements = [...added, ...updated]; + if (!silent && elements.length) { + this._onChange.fire({ elements, added: !!added.length }); } }