From e0cc8f579f6b911a7eb72dea231ad89dace369b8 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 14 Aug 2020 17:29:01 -0700 Subject: [PATCH] Queue replace actions within a filematch because other matches in the file should be considered stale after one replace has been executed Fix #88282 --- .../contrib/search/browser/searchActions.ts | 36 +++++++++---------- .../contrib/search/common/searchModel.ts | 9 +++-- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/vs/workbench/contrib/search/browser/searchActions.ts b/src/vs/workbench/contrib/search/browser/searchActions.ts index 01d1831bb0a..c5eedd23793 100644 --- a/src/vs/workbench/contrib/search/browser/searchActions.ts +++ b/src/vs/workbench/contrib/search/browser/searchActions.ts @@ -683,6 +683,8 @@ export class ReplaceAction extends AbstractSearchAndReplaceAction { static readonly LABEL = nls.localize('match.replace.label', "Replace"); + static runQ = Promise.resolve(); + constructor(private viewer: WorkbenchObjectTree, private element: Match, private viewlet: SearchView, @IReplaceService private readonly replaceService: IReplaceService, @IKeybindingService keyBindingService: IKeybindingService, @@ -691,26 +693,24 @@ export class ReplaceAction extends AbstractSearchAndReplaceAction { super(Constants.ReplaceActionId, appendKeyBindingLabel(ReplaceAction.LABEL, keyBindingService.lookupKeybinding(Constants.ReplaceActionId), keyBindingService), searchReplaceIcon.classNames); } - run(): Promise { + async run(): Promise { this.enabled = false; - return this.element.parent().replace(this.element).then(() => { - const elementToFocus = this.getElementToFocusAfterReplace(); - if (elementToFocus) { - this.viewer.setFocus([elementToFocus], getSelectionKeyboardEvent()); - } + await this.element.parent().replace(this.element); + const elementToFocus = this.getElementToFocusAfterReplace(); + if (elementToFocus) { + this.viewer.setFocus([elementToFocus], getSelectionKeyboardEvent()); + } - return this.getElementToShowReplacePreview(elementToFocus); - }).then(elementToShowReplacePreview => { - this.viewer.domFocus(); + const elementToShowReplacePreview = this.getElementToShowReplacePreview(elementToFocus); + this.viewer.domFocus(); - const useReplacePreview = this.configurationService.getValue().search.useReplacePreview; - if (!useReplacePreview || !elementToShowReplacePreview || this.hasToOpenFile()) { - this.viewlet.open(this.element, true); - } else { - this.replaceService.openReplacePreview(elementToShowReplacePreview, true); - } - }); + const useReplacePreview = this.configurationService.getValue().search.useReplacePreview; + if (!useReplacePreview || !elementToShowReplacePreview || this.hasToOpenFile()) { + this.viewlet.open(this.element, true); + } else { + this.replaceService.openReplacePreview(elementToShowReplacePreview, true); + } } private getElementToFocusAfterReplace(): RenderableMatch { @@ -740,11 +740,11 @@ export class ReplaceAction extends AbstractSearchAndReplaceAction { return elementToFocus!; } - private async getElementToShowReplacePreview(elementToFocus: RenderableMatch): Promise { + private getElementToShowReplacePreview(elementToFocus: RenderableMatch): Match | null { if (this.hasSameParent(elementToFocus)) { return elementToFocus; } - const previousElement = await this.getPreviousElementAfterRemoved(this.viewer, this.element); + const previousElement = this.getPreviousElementAfterRemoved(this.viewer, this.element); if (this.hasSameParent(previousElement)) { return previousElement; } diff --git a/src/vs/workbench/contrib/search/common/searchModel.ts b/src/vs/workbench/contrib/search/common/searchModel.ts index e5bbd712833..983355a2396 100644 --- a/src/vs/workbench/contrib/search/common/searchModel.ts +++ b/src/vs/workbench/contrib/search/common/searchModel.ts @@ -360,9 +360,12 @@ export class FileMatch extends Disposable implements IFileMatch { this._onChange.fire({ didRemove: true }); } - replace(toReplace: Match): Promise { - return this.replaceService.replace(toReplace) - .then(() => this.updatesMatchesForLineAfterReplace(toReplace.range().startLineNumber, false)); + private replaceQ = Promise.resolve(); + async replace(toReplace: Match): Promise { + return this.replaceQ = this.replaceQ.finally(async () => { + await this.replaceService.replace(toReplace); + this.updatesMatchesForLineAfterReplace(toReplace.range().startLineNumber, false); + }); } setSelectedMatch(match: Match | null): void { -- GitLab