提交 9b8401da 编写于 作者: B Benjamin Pasero

fix #74290

上级 553e8d60
......@@ -6,14 +6,14 @@
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { WorkspaceEdit } from 'vs/editor/common/modes';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IProgressRunner } from 'vs/platform/progress/common/progress';
import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress';
export const IBulkEditService = createDecorator<IBulkEditService>('IWorkspaceEditService');
export interface IBulkEditOptions {
editor?: ICodeEditor;
progress?: IProgressRunner;
progress?: IProgress<IProgressStep>;
}
export interface IBulkEditResult {
......
......@@ -74,6 +74,7 @@ export interface IProgressCompositeOptions extends IProgressOptions {
export interface IProgressStep {
message?: string;
increment?: number;
total?: number;
}
export interface IProgressRunner {
......@@ -82,6 +83,8 @@ export interface IProgressRunner {
done(): void;
}
export const emptyProgress: IProgress<IProgressStep> = { report: () => { } };
export const emptyProgressRunner: IProgressRunner = Object.freeze({
total() { },
worked() { },
......
......@@ -13,7 +13,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
import { IModelService } from 'vs/editor/common/services/modelService';
import { IModeService } from 'vs/editor/common/services/modeService';
import { Match, FileMatch, FileMatchOrMatch, ISearchWorkbenchService } from 'vs/workbench/contrib/search/common/searchModel';
import { IProgressRunner } from 'vs/platform/progress/common/progress';
import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress';
import { ITextModelService, ITextModelContentProvider } from 'vs/editor/common/services/resolverService';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { ScrollType } from 'vs/editor/common/editorCommon';
......@@ -101,13 +101,11 @@ export class ReplaceService implements IReplaceService {
) { }
replace(match: Match): Promise<any>;
replace(files: FileMatch[], progress?: IProgressRunner): Promise<any>;
replace(match: FileMatchOrMatch, progress?: IProgressRunner, resource?: URI): Promise<any>;
replace(arg: any, progress: IProgressRunner | undefined = undefined, resource: URI | null = null): Promise<any> {
replace(files: FileMatch[], progress?: IProgress<IProgressStep>): Promise<any>;
replace(match: FileMatchOrMatch, progress?: IProgress<IProgressStep>, resource?: URI): Promise<any>;
replace(arg: any, progress: IProgress<IProgressStep> | undefined = undefined, resource: URI | null = null): Promise<any> {
const edits: ResourceTextEdit[] = this.createEdits(arg, resource);
return this.bulkEditorService.apply({ edits }, { progress }).then(() => this.textFileService.saveAll(edits.map(e => e.resource)));
}
openReplacePreview(element: FileMatchOrMatch, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): Promise<any> {
......
......@@ -33,7 +33,7 @@ import { FileChangesEvent, FileChangeType, IFileService } from 'vs/platform/file
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { TreeResourceNavigator2, WorkbenchObjectTree, getSelectionKeyboardEvent } from 'vs/platform/list/browser/listService';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { ILocalProgressService, IProgressService } from 'vs/platform/progress/common/progress';
import { IProgressService, IProgressStep, IProgress } from 'vs/platform/progress/common/progress';
import { IPatternInfo, ISearchComplete, ISearchConfiguration, ISearchConfigurationProperties, ITextQuery, SearchErrorCode, VIEW_ID, VIEWLET_ID } from 'vs/workbench/services/search/common/search';
import { ISearchHistoryService, ISearchHistoryValues } from 'vs/workbench/contrib/search/common/searchHistoryService';
import { diffInserted, diffInsertedOutline, diffRemoved, diffRemovedOutline, editorFindMatchHighlight, editorFindMatchHighlightBorder, listActiveSelectionForeground } from 'vs/platform/theme/common/colorRegistry';
......@@ -129,7 +129,6 @@ export class SearchView extends ViewletPanel {
options: IViewletPanelOptions,
@IFileService private readonly fileService: IFileService,
@IEditorService private readonly editorService: IEditorService,
@ILocalProgressService private readonly localProgressService: ILocalProgressService,
@IProgressService private readonly progressService: IProgressService,
@INotificationService private readonly notificationService: INotificationService,
@IDialogService private readonly dialogService: IDialogService,
......@@ -518,13 +517,19 @@ export class SearchView extends ViewletPanel {
return;
}
const progressRunner = this.localProgressService.show(100);
const occurrences = this.viewModel.searchResult.count();
const fileCount = this.viewModel.searchResult.fileCount();
const replaceValue = this.searchWidget.getReplaceValue() || '';
const afterReplaceAllMessage = this.buildAfterReplaceAllMessage(occurrences, fileCount, replaceValue);
let progressComplete: () => void;
let progressReporter: IProgress<IProgressStep>;
this.progressService.withProgress({ location: VIEWLET_ID, delay: 100, total: occurrences }, p => {
progressReporter = p;
return new Promise(resolve => progressComplete = resolve);
});
const confirmation: IConfirmation = {
title: nls.localize('replaceAll.confirmation.title', "Replace All"),
message: this.buildReplaceAllConfirmationMessage(occurrences, fileCount, replaceValue),
......@@ -535,12 +540,12 @@ export class SearchView extends ViewletPanel {
this.dialogService.confirm(confirmation).then(res => {
if (res.confirmed) {
this.searchWidget.setReplaceAllActionState(false);
this.viewModel.searchResult.replaceAll(progressRunner).then(() => {
progressRunner.done();
this.viewModel.searchResult.replaceAll(progressReporter).then(() => {
progressComplete();
const messageEl = this.clearMessage();
dom.append(messageEl, $('p', undefined, afterReplaceAllMessage));
}, (error) => {
progressRunner.done();
progressComplete();
errors.isPromiseCanceledError(error);
this.notificationService.error(error);
});
......
......@@ -5,7 +5,7 @@
import { Match, FileMatch, FileMatchOrMatch } from 'vs/workbench/contrib/search/common/searchModel';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IProgressRunner } from 'vs/platform/progress/common/progress';
import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress';
export const IReplaceService = createDecorator<IReplaceService>('replaceService');
......@@ -22,7 +22,7 @@ export interface IReplaceService {
* Replace all the matches from the given file matches in the files
* You can also pass the progress runner to update the progress of replacing.
*/
replace(files: FileMatch[], progress?: IProgressRunner): Promise<any>;
replace(files: FileMatch[], progress?: IProgress<IProgressStep>): Promise<any>;
/**
* Opens the replace preview for given file match or match
......
......@@ -18,7 +18,7 @@ import { FindMatch, IModelDeltaDecoration, ITextModel, OverviewRulerLane, Tracke
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
import { IModelService } from 'vs/editor/common/services/modelService';
import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IProgressRunner } from 'vs/platform/progress/common/progress';
import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress';
import { ReplacePattern } from 'vs/workbench/services/search/common/replace';
import { IFileMatch, IPatternInfo, ISearchComplete, ISearchProgressItem, ISearchService, ITextQuery, ITextSearchPreviewOptions, ITextSearchMatch, ITextSearchStats, resultIsMatch, ISearchRange, OneLineRange } from 'vs/workbench/services/search/common/search';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
......@@ -736,10 +736,10 @@ export class SearchResult extends Disposable {
return this.getFolderMatch(match.resource()).replace(match);
}
replaceAll(progressRunner: IProgressRunner): Promise<any> {
replaceAll(progress: IProgress<IProgressStep>): Promise<any> {
this.replacingAll = true;
const promise = this.replaceService.replace(this.matches(), progressRunner);
const promise = this.replaceService.replace(this.matches(), progress);
const onDone = Event.stopwatch(Event.fromPromise(promise));
/* __GDPR__
"replaceAll.started" : {
......
......@@ -18,7 +18,7 @@ import { localize } from 'vs/nls';
import { IFileService, FileSystemProviderCapabilities } from 'vs/platform/files/common/files';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ILogService } from 'vs/platform/log/common/log';
import { emptyProgressRunner, IProgress, IProgressRunner } from 'vs/platform/progress/common/progress';
import { IProgress, IProgressStep, emptyProgress } from 'vs/platform/progress/common/progress';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { ILabelService } from 'vs/platform/label/common/label';
......@@ -231,11 +231,11 @@ export class BulkEdit {
private _edits: Edit[] = [];
private _editor: ICodeEditor | undefined;
private _progress?: IProgressRunner;
private _progress: IProgress<IProgressStep>;
constructor(
editor: ICodeEditor | undefined,
progress: IProgressRunner | undefined,
progress: IProgress<IProgressStep> | undefined,
@ILogService private readonly _logService: ILogService,
@ITextModelService private readonly _textModelService: ITextModelService,
@IFileService private readonly _fileService: IFileService,
......@@ -244,7 +244,7 @@ export class BulkEdit {
@IConfigurationService private readonly _configurationService: IConfigurationService
) {
this._editor = editor;
this._progress = progress || emptyProgressRunner;
this._progress = progress || emptyProgress;
}
add(edits: Edit[] | Edit): void {
......@@ -294,10 +294,9 @@ export class BulkEdit {
// define total work and progress callback
// for child operations
if (this._progress) {
this._progress.total(total);
}
let progress: IProgress<void> = { report: _ => this._progress && this._progress.worked(1) };
this._progress.report({ total });
let progress: IProgress<void> = { report: _ => this._progress.report({ increment: 1 }) };
// do it.
for (const group of groups) {
......
......@@ -298,12 +298,17 @@ export class ProgressService extends Disposable implements IProgressService {
if (typeof progress.increment === 'number') {
progressRunner.worked(progress.increment);
}
if (typeof progress.total === 'number') {
progressRunner.total(progress.total);
}
}
});
if (compositeProgressService) {
if (typeof options.total === 'number') {
progressRunner = compositeProgressService.show(options.total, options.delay);
promise.catch(() => undefined /* ignore */).finally(() => progressRunner ? progressRunner.done() : undefined);
} else {
compositeProgressService.showWhile(promise, options.delay);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册