From 6681c86cfdba7e415d6eeea99242b35bbd2a7220 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sat, 11 Nov 2017 17:56:57 -0800 Subject: [PATCH] Fix #31260 - implement 'replace all' button for folder match in search viewlet --- .../parts/search/browser/searchActions.ts | 24 +++++++++++++++++++ .../parts/search/browser/searchResultsView.ts | 12 ++++++++-- .../parts/search/common/searchModel.ts | 7 ++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/search/browser/searchActions.ts b/src/vs/workbench/parts/search/browser/searchActions.ts index fc811e488ab..09e290ea49c 100644 --- a/src/vs/workbench/parts/search/browser/searchActions.ts +++ b/src/vs/workbench/parts/search/browser/searchActions.ts @@ -604,6 +604,30 @@ export class ReplaceAllAction extends AbstractSearchAndReplaceAction { } } +export class ReplaceAllInFolderAction extends AbstractSearchAndReplaceAction { + + constructor(private viewer: ITree, private folderMatch: FolderMatch, + @IKeybindingService keyBindingService: IKeybindingService, + @ITelemetryService private telemetryService: ITelemetryService + ) { + super(Constants.ReplaceAllInFileActionId, nls.localize('file.replaceAll.label', "Replace All"), 'action-replace-all'); + } + + public async run(): TPromise { + /* __GDPR__ + "replaceAllInFolder.action.selected" : {} + */ + this.telemetryService.publicLog('replaceAllInFolder.action.selected'); + let nextFocusElement = this.getElementToFocusAfterRemoved(this.viewer, this.folderMatch); + await this.folderMatch.replaceAll(); + + if (nextFocusElement) { + this.viewer.setFocus(nextFocusElement); + } + this.viewer.DOMFocus(); + } +} + export class ReplaceAction extends AbstractSearchAndReplaceAction { constructor(private viewer: ITree, private element: Match, private viewlet: SearchViewlet, diff --git a/src/vs/workbench/parts/search/browser/searchResultsView.ts b/src/vs/workbench/parts/search/browser/searchResultsView.ts index 183c34f1c0e..b38570f3db1 100644 --- a/src/vs/workbench/parts/search/browser/searchResultsView.ts +++ b/src/vs/workbench/parts/search/browser/searchResultsView.ts @@ -17,7 +17,7 @@ import { Match, SearchResult, FileMatch, FileMatchOrMatch, SearchModel, FolderMa import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { Range } from 'vs/editor/common/core/range'; import { SearchViewlet } from 'vs/workbench/parts/search/browser/searchViewlet'; -import { RemoveAction, ReplaceAllAction, ReplaceAction } from 'vs/workbench/parts/search/browser/searchActions'; +import { RemoveAction, ReplaceAllAction, ReplaceAction, ReplaceAllInFolderAction } from 'vs/workbench/parts/search/browser/searchActions'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { attachBadgeStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; @@ -251,7 +251,15 @@ export class SearchRenderer extends Disposable implements IRenderer { templateData.badge.setTitleFormat(count > 1 ? nls.localize('searchFileMatches', "{0} files found", count) : nls.localize('searchFileMatch', "{0} file found", count)); templateData.actions.clear(); - templateData.actions.push([new RemoveAction(tree, folderMatch)], { icon: true, label: false }); + + const input = tree.getInput(); + const actions: IAction[] = []; + if (input.searchModel.isReplaceActive() && count > 0) { + actions.push(this.instantiationService.createInstance(ReplaceAllInFolderAction, tree, folderMatch)); + } + + actions.push(new RemoveAction(tree, folderMatch)); + templateData.actions.push(actions, { icon: true, label: false }); } private renderFileMatch(tree: ITree, fileMatch: FileMatch, templateData: IFileMatchTemplate): void { diff --git a/src/vs/workbench/parts/search/common/searchModel.ts b/src/vs/workbench/parts/search/common/searchModel.ts index 890f10ff3d2..2fe02b67166 100644 --- a/src/vs/workbench/parts/search/common/searchModel.ts +++ b/src/vs/workbench/parts/search/common/searchModel.ts @@ -422,6 +422,13 @@ export class FolderMatch extends Disposable { }); } + public replaceAll(): TPromise { + const matches = this.matches(); + return this.replaceService.replace(matches).then(() => { + matches.forEach(match => this.doRemove(match, false, true)); + }); + } + public matches(): FileMatch[] { return this._fileMatches.values(); } -- GitLab