Path: blob/main/src/vs/editor/contrib/find/browser/replaceAllCommand.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Range } from '../../../common/core/range.js';6import { Selection } from '../../../common/core/selection.js';7import { ICommand, ICursorStateComputerData, IEditOperationBuilder } from '../../../common/editorCommon.js';8import { ITextModel } from '../../../common/model.js';910interface IEditOperation {11range: Range;12text: string;13}1415export class ReplaceAllCommand implements ICommand {1617private readonly _editorSelection: Selection;18private _trackedEditorSelectionId: string | null;19private readonly _ranges: Range[];20private readonly _replaceStrings: string[];2122constructor(editorSelection: Selection, ranges: Range[], replaceStrings: string[]) {23this._editorSelection = editorSelection;24this._ranges = ranges;25this._replaceStrings = replaceStrings;26this._trackedEditorSelectionId = null;27}2829public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void {30if (this._ranges.length > 0) {31// Collect all edit operations32const ops: IEditOperation[] = [];33for (let i = 0; i < this._ranges.length; i++) {34ops.push({35range: this._ranges[i],36text: this._replaceStrings[i]37});38}3940// Sort them in ascending order by range starts41ops.sort((o1, o2) => {42return Range.compareRangesUsingStarts(o1.range, o2.range);43});4445// Merge operations that touch each other46const resultOps: IEditOperation[] = [];47let previousOp = ops[0];48for (let i = 1; i < ops.length; i++) {49if (previousOp.range.endLineNumber === ops[i].range.startLineNumber && previousOp.range.endColumn === ops[i].range.startColumn) {50// These operations are one after another and can be merged51previousOp.range = previousOp.range.plusRange(ops[i].range);52previousOp.text = previousOp.text + ops[i].text;53} else {54resultOps.push(previousOp);55previousOp = ops[i];56}57}58resultOps.push(previousOp);5960for (const op of resultOps) {61builder.addEditOperation(op.range, op.text);62}63}6465this._trackedEditorSelectionId = builder.trackSelection(this._editorSelection);66}6768public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {69return helper.getTrackedSelection(this._trackedEditorSelectionId!);70}71}727374