From 46dbb7973cb197a87f7a1fd1babe41e600965279 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 18 Mar 2020 10:09:41 +0100 Subject: [PATCH] Compress consecutive edits in undo stack --- src/vs/editor/common/model.ts | 26 ++-- src/vs/editor/common/model/editStack.ts | 15 ++- .../pieceTreeTextBuffer.ts | 116 ++++++++++-------- src/vs/editor/common/model/textChange.ts | 46 ++++--- src/vs/editor/common/model/textModel.ts | 41 +++++-- .../test/browser/controller/cursor.test.ts | 2 +- .../model/benchmark/operations.benchmark.ts | 10 +- .../benchmark/searchNReplace.benchmark.ts | 4 +- .../model/editableTextModelTestUtils.ts | 4 +- .../linesTextBuffer/linesTextBuffer.test.ts | 4 +- .../common/model/modelEditOperation.test.ts | 4 +- src/vs/monaco.d.ts | 9 +- 12 files changed, 150 insertions(+), 131 deletions(-) diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index 5b6764ea1b1..007653362fd 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -15,6 +15,7 @@ import { SearchData } from 'vs/editor/common/model/textModelSearch'; import { LanguageId, LanguageIdentifier, FormattingOptions } from 'vs/editor/common/modes'; import { ThemeColor } from 'vs/platform/theme/common/themeService'; import { MultilineTokens, MultilineTokens2 } from 'vs/editor/common/model/tokensStore'; +import { TextChange } from 'vs/editor/common/model/textChange'; /** * Vertical Lane in the overview ruler of the editor. @@ -373,21 +374,13 @@ export interface IValidEditOperation { */ range: Range; /** - * The text to replace with. This can be null to emulate a simple delete. + * The text to replace with. This can be empty to emulate a simple delete. */ - text: string | null; + text: string; /** - * This indicates that this operation has "insert" semantics. - * i.e. forceMoveMarkers = true => if `range` is collapsed, all markers at the position will be moved. + * @internal */ - forceMoveMarkers: boolean; -} - -/** - * @internal - */ -export interface IValidEditOperations { - operations: IValidEditOperation[]; + textChange: TextChange; } /** @@ -1106,7 +1099,12 @@ export interface ITextModel { /** * @internal */ - _applyUndoRedoEdits(edits: IValidEditOperations[], eol: EndOfLineSequence, isUndoing: boolean, isRedoing: boolean, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): IValidEditOperations[]; + _applyUndo(changes: TextChange[], eol: EndOfLineSequence, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): void; + + /** + * @internal + */ + _applyRedo(changes: TextChange[], eol: EndOfLineSequence, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): void; /** * Undo edit operations until the first previous stop point created by `pushStackElement`. @@ -1285,7 +1283,7 @@ export interface ITextBuffer { getLineLastNonWhitespaceColumn(lineNumber: number): number; setEOL(newEOL: '\r\n' | '\n'): void; - applyEdits(rawOperations: ValidAnnotatedEditOperation[], recordTrimAutoWhitespace: boolean): ApplyEditsResult; + applyEdits(rawOperations: ValidAnnotatedEditOperation[], recordTrimAutoWhitespace: boolean, computeUndoEdits: boolean): ApplyEditsResult; findMatchesLineByLine(searchRange: Range, searchData: SearchData, captureMatches: boolean, limitResultCount: number): FindMatch[]; } diff --git a/src/vs/editor/common/model/editStack.ts b/src/vs/editor/common/model/editStack.ts index 05baaec0e31..cbc7a4b32a4 100644 --- a/src/vs/editor/common/model/editStack.ts +++ b/src/vs/editor/common/model/editStack.ts @@ -6,11 +6,12 @@ import * as nls from 'vs/nls'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Selection } from 'vs/editor/common/core/selection'; -import { EndOfLineSequence, ICursorStateComputer, IIdentifiedSingleEditOperation, IValidEditOperation, ITextModel, IValidEditOperations } from 'vs/editor/common/model'; +import { EndOfLineSequence, ICursorStateComputer, IIdentifiedSingleEditOperation, IValidEditOperation, ITextModel } from 'vs/editor/common/model'; import { TextModel } from 'vs/editor/common/model/textModel'; import { IUndoRedoService, IResourceUndoRedoElement, UndoRedoElementType, IWorkspaceUndoRedoElement } from 'vs/platform/undoRedo/common/undoRedo'; import { URI } from 'vs/base/common/uri'; import { getComparisonKey as uriGetComparisonKey } from 'vs/base/common/resources'; +import { TextChange, compressConsecutiveTextChanges } from 'vs/editor/common/model/textChange'; export class SingleModelEditStackElement implements IResourceUndoRedoElement { @@ -24,7 +25,7 @@ export class SingleModelEditStackElement implements IResourceUndoRedoElement { private _afterVersionId: number; private _afterEOL: EndOfLineSequence; private _afterCursorState: Selection[] | null; - private _edits: IValidEditOperations[]; + private _changes: TextChange[]; public get resource(): URI { return this.model.uri; @@ -40,7 +41,7 @@ export class SingleModelEditStackElement implements IResourceUndoRedoElement { this._afterVersionId = this._beforeVersionId; this._afterEOL = this._beforeEOL; this._afterCursorState = this._beforeCursorState; - this._edits = []; + this._changes = []; } public setModel(model: ITextModel): void { @@ -53,7 +54,7 @@ export class SingleModelEditStackElement implements IResourceUndoRedoElement { public append(model: ITextModel, operations: IValidEditOperation[], afterEOL: EndOfLineSequence, afterVersionId: number, afterCursorState: Selection[] | null): void { if (operations.length > 0) { - this._edits.push({ operations: operations }); + this._changes = compressConsecutiveTextChanges(this._changes, operations.map(op => op.textChange)); } this._afterEOL = afterEOL; this._afterVersionId = afterVersionId; @@ -66,13 +67,11 @@ export class SingleModelEditStackElement implements IResourceUndoRedoElement { public undo(): void { this._isOpen = false; - this._edits.reverse(); - this._edits = this.model._applyUndoRedoEdits(this._edits, this._beforeEOL, true, false, this._beforeVersionId, this._beforeCursorState); + this.model._applyUndo(this._changes, this._beforeEOL, this._beforeVersionId, this._beforeCursorState); } public redo(): void { - this._edits.reverse(); - this._edits = this.model._applyUndoRedoEdits(this._edits, this._afterEOL, false, true, this._afterVersionId, this._afterCursorState); + this.model._applyRedo(this._changes, this._afterEOL, this._afterVersionId, this._afterCursorState); } } diff --git a/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts index 1de38d90dcb..e56041e1e3f 100644 --- a/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts +++ b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts @@ -10,6 +10,7 @@ import { ApplyEditsResult, EndOfLinePreference, FindMatch, IInternalModelContent import { PieceTreeBase, StringBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase'; import { SearchData } from 'vs/editor/common/model/textModelSearch'; import { countEOL, StringEOL } from 'vs/editor/common/model/tokensStore'; +import { TextChange } from 'vs/editor/common/model/textChange'; export interface IValidatedEditOperation { sortIndex: number; @@ -17,7 +18,7 @@ export interface IValidatedEditOperation { range: Range; rangeOffset: number; rangeLength: number; - text: string | null; + text: string; eolCount: number; firstLineLength: number; lastLineLength: number; @@ -205,7 +206,7 @@ export class PieceTreeTextBuffer implements ITextBuffer { this._pieceTree.setEOL(newEOL); } - public applyEdits(rawOperations: ValidAnnotatedEditOperation[], recordTrimAutoWhitespace: boolean): ApplyEditsResult { + public applyEdits(rawOperations: ValidAnnotatedEditOperation[], recordTrimAutoWhitespace: boolean, computeUndoEdits: boolean): ApplyEditsResult { let mightContainRTL = this._mightContainRTL; let mightContainNonBasicASCII = this._mightContainNonBasicASCII; let canReduceOperations = true; @@ -225,7 +226,7 @@ export class PieceTreeTextBuffer implements ITextBuffer { mightContainNonBasicASCII = !strings.isBasicASCII(op.text); } - let validText: string | null = null; + let validText = ''; let eolCount = 0; let firstLineLength = 0; let lastLineLength = 0; @@ -260,66 +261,75 @@ export class PieceTreeTextBuffer implements ITextBuffer { // Sort operations ascending operations.sort(PieceTreeTextBuffer._sortOpsAscending); - let hasTouchingRanges = false; - for (let i = 0, count = operations.length - 1; i < count; i++) { - let rangeEnd = operations[i].range.getEndPosition(); - let nextRangeStart = operations[i + 1].range.getStartPosition(); - - if (nextRangeStart.isBeforeOrEqual(rangeEnd)) { - if (nextRangeStart.isBefore(rangeEnd)) { - // overlapping ranges - throw new Error('Overlapping ranges are not allowed!'); - } - hasTouchingRanges = true; - } - } - if (canReduceOperations) { operations = this._reduceOperations(operations); } // Delta encode operations - let reverseRanges = PieceTreeTextBuffer._getInverseEditRanges(operations); + let reverseRanges = (computeUndoEdits || recordTrimAutoWhitespace ? PieceTreeTextBuffer._getInverseEditRanges(operations) : []); let newTrimAutoWhitespaceCandidates: { lineNumber: number, oldContent: string }[] = []; - - for (let i = 0; i < operations.length; i++) { - let op = operations[i]; - let reverseRange = reverseRanges[i]; - - if (recordTrimAutoWhitespace && op.isAutoWhitespaceEdit && op.range.isEmpty()) { - // Record already the future line numbers that might be auto whitespace removal candidates on next edit - for (let lineNumber = reverseRange.startLineNumber; lineNumber <= reverseRange.endLineNumber; lineNumber++) { - let currentLineContent = ''; - if (lineNumber === reverseRange.startLineNumber) { - currentLineContent = this.getLineContent(op.range.startLineNumber); - if (strings.firstNonWhitespaceIndex(currentLineContent) !== -1) { - continue; + if (recordTrimAutoWhitespace) { + for (let i = 0; i < operations.length; i++) { + let op = operations[i]; + let reverseRange = reverseRanges[i]; + + if (op.isAutoWhitespaceEdit && op.range.isEmpty()) { + // Record already the future line numbers that might be auto whitespace removal candidates on next edit + for (let lineNumber = reverseRange.startLineNumber; lineNumber <= reverseRange.endLineNumber; lineNumber++) { + let currentLineContent = ''; + if (lineNumber === reverseRange.startLineNumber) { + currentLineContent = this.getLineContent(op.range.startLineNumber); + if (strings.firstNonWhitespaceIndex(currentLineContent) !== -1) { + continue; + } } + newTrimAutoWhitespaceCandidates.push({ lineNumber: lineNumber, oldContent: currentLineContent }); } - newTrimAutoWhitespaceCandidates.push({ lineNumber: lineNumber, oldContent: currentLineContent }); } } } let reverseOperations: IReverseSingleEditOperation[] = []; - for (let i = 0; i < operations.length; i++) { - let op = operations[i]; - let reverseRange = reverseRanges[i]; + if (computeUndoEdits) { - reverseOperations[i] = { - sortIndex: op.sortIndex, - identifier: op.identifier, - range: reverseRange, - text: this.getValueInRange(op.range), - forceMoveMarkers: op.forceMoveMarkers - }; - } + let hasTouchingRanges = false; + for (let i = 0, count = operations.length - 1; i < count; i++) { + let rangeEnd = operations[i].range.getEndPosition(); + let nextRangeStart = operations[i + 1].range.getStartPosition(); + + if (nextRangeStart.isBeforeOrEqual(rangeEnd)) { + if (nextRangeStart.isBefore(rangeEnd)) { + // overlapping ranges + throw new Error('Overlapping ranges are not allowed!'); + } + hasTouchingRanges = true; + } + } - // Can only sort reverse operations when the order is not significant - if (!hasTouchingRanges) { - reverseOperations.sort((a, b) => a.sortIndex - b.sortIndex); + let reverseRangeDeltaOffset = 0; + for (let i = 0; i < operations.length; i++) { + const op = operations[i]; + const reverseRange = reverseRanges[i]; + const bufferText = this.getValueInRange(op.range); + const reverseRangeOffset = op.rangeOffset + reverseRangeDeltaOffset; + reverseRangeDeltaOffset += (op.text.length - bufferText.length); + + reverseOperations[i] = { + sortIndex: op.sortIndex, + identifier: op.identifier, + range: reverseRange, + text: bufferText, + textChange: new TextChange(op.rangeOffset, bufferText, reverseRangeOffset, op.text) + }; + } + + // Can only sort reverse operations when the order is not significant + if (!hasTouchingRanges) { + reverseOperations.sort((a, b) => a.sortIndex - b.sortIndex); + } } + this._mightContainRTL = mightContainRTL; this._mightContainNonBasicASCII = mightContainNonBasicASCII; @@ -393,7 +403,7 @@ export class PieceTreeTextBuffer implements ITextBuffer { result.push(this.getValueInRange(new Range(lastEndLineNumber, lastEndColumn, range.startLineNumber, range.startColumn))); // (2) -- Push new text - if (operation.text) { + if (operation.text.length > 0) { result.push(operation.text); } @@ -433,17 +443,15 @@ export class PieceTreeTextBuffer implements ITextBuffer { const endLineNumber = op.range.endLineNumber; const endColumn = op.range.endColumn; - if (startLineNumber === endLineNumber && startColumn === endColumn && (!op.text || op.text.length === 0)) { + if (startLineNumber === endLineNumber && startColumn === endColumn && op.text.length === 0) { // no-op continue; } - const text = op.text ? op.text : ''; - - if (text) { + if (op.text) { // replacement this._pieceTree.delete(op.rangeOffset, op.rangeLength); - this._pieceTree.insert(op.rangeOffset, text, true); + this._pieceTree.insert(op.rangeOffset, op.text, true); } else { // deletion @@ -454,7 +462,7 @@ export class PieceTreeTextBuffer implements ITextBuffer { contentChanges.push({ range: contentChangeRange, rangeLength: op.rangeLength, - text: text, + text: op.text, rangeOffset: op.rangeOffset, forceMoveMarkers: op.forceMoveMarkers }); @@ -503,7 +511,7 @@ export class PieceTreeTextBuffer implements ITextBuffer { let resultRange: Range; - if (op.text && op.text.length > 0) { + if (op.text.length > 0) { // the operation inserts something const lineCount = op.eolCount + 1; diff --git a/src/vs/editor/common/model/textChange.ts b/src/vs/editor/common/model/textChange.ts index 258d700abab..712e3a754bb 100644 --- a/src/vs/editor/common/model/textChange.ts +++ b/src/vs/editor/common/model/textChange.ts @@ -4,35 +4,33 @@ *--------------------------------------------------------------------------------------------*/ export class TextChange { - public readonly oldPosition: number; - public readonly oldLength: number; - public readonly oldEnd: number; - public readonly oldText: string; - public readonly newPosition: number; - public readonly newLength: number; - public readonly newEnd: number; - public readonly newText: string; - constructor( - oldPosition: number, - oldText: string, - newPosition: number, - newText: string - ) { - this.oldPosition = oldPosition; - this.oldLength = oldText.length; - this.oldEnd = this.oldPosition + this.oldLength; - this.oldText = oldText; - - this.newPosition = newPosition; - this.newLength = newText.length; - this.newEnd = this.newPosition + this.newLength; - this.newText = newText; + public get oldLength(): number { + return this.oldText.length; + } + + public get oldEnd(): number { + return this.oldPosition + this.oldText.length; + } + + public get newLength(): number { + return this.newText.length; } + + public get newEnd(): number { + return this.newPosition + this.newText.length; + } + + constructor( + public readonly oldPosition: number, + public readonly oldText: string, + public readonly newPosition: number, + public readonly newText: string + ) { } } export function compressConsecutiveTextChanges(prevEdits: TextChange[] | null, currEdits: TextChange[]): TextChange[] { - if (prevEdits === null) { + if (prevEdits === null || prevEdits.length === 0) { return currEdits; } const compressor = new TextChangeCompressor(prevEdits, currEdits); diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index 3406a061fca..8b1208d64c1 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -37,6 +37,7 @@ import { Color } from 'vs/base/common/color'; import { Constants } from 'vs/base/common/uint'; import { EditorTheme } from 'vs/editor/common/view/viewContext'; import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; +import { TextChange } from 'vs/editor/common/model/textChange'; function createTextBufferBuilder() { return new PieceTreeTextBufferBuilder(); @@ -1283,19 +1284,39 @@ export class TextModel extends Disposable implements model.ITextModel { return this._commandManager.pushEditOperation(beforeCursorState, editOperations, cursorStateComputer); } - _applyUndoRedoEdits(edits: model.IValidEditOperations[], eol: model.EndOfLineSequence, isUndoing: boolean, isRedoing: boolean, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): model.IValidEditOperations[] { + _applyUndo(changes: TextChange[], eol: model.EndOfLineSequence, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): void { + const edits = changes.map((change) => { + const rangeStart = this.getPositionAt(change.newPosition); + const rangeEnd = this.getPositionAt(change.newEnd); + return { + range: new Range(rangeStart.lineNumber, rangeStart.column, rangeEnd.lineNumber, rangeEnd.column), + text: change.oldText + }; + }); + this._applyUndoRedoEdits(edits, eol, true, false, resultingAlternativeVersionId, resultingSelection); + } + + _applyRedo(changes: TextChange[], eol: model.EndOfLineSequence, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): void { + const edits = changes.map((change) => { + const rangeStart = this.getPositionAt(change.oldPosition); + const rangeEnd = this.getPositionAt(change.oldEnd); + return { + range: new Range(rangeStart.lineNumber, rangeStart.column, rangeEnd.lineNumber, rangeEnd.column), + text: change.newText + }; + }); + this._applyUndoRedoEdits(edits, eol, false, true, resultingAlternativeVersionId, resultingSelection); + } + + private _applyUndoRedoEdits(edits: model.IIdentifiedSingleEditOperation[], eol: model.EndOfLineSequence, isUndoing: boolean, isRedoing: boolean, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): void { try { this._onDidChangeDecorations.beginDeferredEmit(); this._eventEmitter.beginDeferredEmit(); this._isUndoing = isUndoing; this._isRedoing = isRedoing; - let reverseEdits: model.IValidEditOperations[] = []; - for (let i = 0, len = edits.length; i < len; i++) { - reverseEdits[i] = { operations: this.applyEdits(edits[i].operations) }; - } + this.applyEdits(edits, false); this.setEOL(eol); this._overwriteAlternativeVersionId(resultingAlternativeVersionId); - return reverseEdits; } finally { this._isUndoing = false; this._isRedoing = false; @@ -1304,21 +1325,21 @@ export class TextModel extends Disposable implements model.ITextModel { } } - public applyEdits(rawOperations: model.IIdentifiedSingleEditOperation[]): model.IValidEditOperation[] { + public applyEdits(rawOperations: model.IIdentifiedSingleEditOperation[], computeUndoEdits: boolean = true): model.IValidEditOperation[] { try { this._onDidChangeDecorations.beginDeferredEmit(); this._eventEmitter.beginDeferredEmit(); - return this._doApplyEdits(this._validateEditOperations(rawOperations)); + return this._doApplyEdits(this._validateEditOperations(rawOperations), computeUndoEdits); } finally { this._eventEmitter.endDeferredEmit(); this._onDidChangeDecorations.endDeferredEmit(); } } - private _doApplyEdits(rawOperations: model.ValidAnnotatedEditOperation[]): model.IValidEditOperation[] { + private _doApplyEdits(rawOperations: model.ValidAnnotatedEditOperation[], computeUndoEdits: boolean): model.IValidEditOperation[] { const oldLineCount = this._buffer.getLineCount(); - const result = this._buffer.applyEdits(rawOperations, this._options.trimAutoWhitespace); + const result = this._buffer.applyEdits(rawOperations, this._options.trimAutoWhitespace, computeUndoEdits); const newLineCount = this._buffer.getLineCount(); const contentChanges = result.changes; diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index 34902600555..3175d1b0228 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -1348,7 +1348,7 @@ suite('Editor Controller - Regression tests', () => { CoreEditingCommands.Undo.runEditorCommand(null, editor, null); assert.equal(model.getLineContent(1), 'Hello world '); - assertCursor(cursor, new Position(1, 13)); + assertCursor(cursor, new Selection(1, 12, 1, 13)); CoreEditingCommands.Undo.runEditorCommand(null, editor, null); assert.equal(model.getLineContent(1), 'Hello world'); diff --git a/src/vs/editor/test/common/model/benchmark/operations.benchmark.ts b/src/vs/editor/test/common/model/benchmark/operations.benchmark.ts index 4ec19305751..ded9745ef09 100644 --- a/src/vs/editor/test/common/model/benchmark/operations.benchmark.ts +++ b/src/vs/editor/test/common/model/benchmark/operations.benchmark.ts @@ -54,7 +54,7 @@ for (let fileSize of fileSizes) { fn: (textBuffer) => { // for line model, this loop doesn't reflect the real situation. for (const edit of edits) { - textBuffer.applyEdits([edit], false); + textBuffer.applyEdits([edit], false, false); } } }); @@ -67,7 +67,7 @@ for (let fileSize of fileSizes) { }, preCycle: (textBuffer) => { for (const edit of edits) { - textBuffer.applyEdits([edit], false); + textBuffer.applyEdits([edit], false, false); } return textBuffer; }, @@ -91,7 +91,7 @@ for (let fileSize of fileSizes) { }, preCycle: (textBuffer) => { for (const edit of edits) { - textBuffer.applyEdits([edit], false); + textBuffer.applyEdits([edit], false, false); } return textBuffer; }, @@ -121,7 +121,7 @@ for (let fileSize of fileSizes) { }, preCycle: (textBuffer) => { for (const edit of edits) { - textBuffer.applyEdits([edit], false); + textBuffer.applyEdits([edit], false, false); } return textBuffer; }, @@ -134,4 +134,4 @@ for (let fileSize of fileSizes) { editsSuite.run(); } -} \ No newline at end of file +} diff --git a/src/vs/editor/test/common/model/benchmark/searchNReplace.benchmark.ts b/src/vs/editor/test/common/model/benchmark/searchNReplace.benchmark.ts index ab86d7e0a81..aecb8ad46ca 100644 --- a/src/vs/editor/test/common/model/benchmark/searchNReplace.benchmark.ts +++ b/src/vs/editor/test/common/model/benchmark/searchNReplace.benchmark.ts @@ -41,10 +41,10 @@ for (let fileSize of fileSizes) { return textBuffer; }, fn: (textBuffer) => { - textBuffer.applyEdits(edits.slice(0, i), false); + textBuffer.applyEdits(edits.slice(0, i), false, false); } }); } replaceSuite.run(); -} \ No newline at end of file +} diff --git a/src/vs/editor/test/common/model/editableTextModelTestUtils.ts b/src/vs/editor/test/common/model/editableTextModelTestUtils.ts index e1e4b5c999e..2ec1be624c0 100644 --- a/src/vs/editor/test/common/model/editableTextModelTestUtils.ts +++ b/src/vs/editor/test/common/model/editableTextModelTestUtils.ts @@ -36,8 +36,8 @@ export function testApplyEditsWithSyncedModels(original: string[], edits: IIdent identifier: edit.identifier, range: edit.range, text: edit.text, - forceMoveMarkers: edit.forceMoveMarkers, - isAutoWhitespaceEdit: edit.isAutoWhitespaceEdit + forceMoveMarkers: edit.forceMoveMarkers || false, + isAutoWhitespaceEdit: edit.isAutoWhitespaceEdit || false }; }; // Assert the inverse of the inverse edits are the original edits diff --git a/src/vs/editor/test/common/model/linesTextBuffer/linesTextBuffer.test.ts b/src/vs/editor/test/common/model/linesTextBuffer/linesTextBuffer.test.ts index a0817667d00..4c9bd0d183c 100644 --- a/src/vs/editor/test/common/model/linesTextBuffer/linesTextBuffer.test.ts +++ b/src/vs/editor/test/common/model/linesTextBuffer/linesTextBuffer.test.ts @@ -18,7 +18,7 @@ suite('PieceTreeTextBuffer._getInverseEdits', () => { range: new Range(startLineNumber, startColumn, endLineNumber, endColumn), rangeOffset: 0, rangeLength: 0, - text: text ? text.join('\n') : null, + text: text ? text.join('\n') : '', eolCount: text ? text.length - 1 : 0, firstLineLength: text ? text[0].length : 0, lastLineLength: text ? text[text.length - 1].length : 0, @@ -272,7 +272,7 @@ suite('PieceTreeTextBuffer._toSingleEditOperation', () => { range: new Range(startLineNumber, startColumn, endLineNumber, endColumn), rangeOffset: rangeOffset, rangeLength: rangeLength, - text: text ? text.join('\n') : null, + text: text ? text.join('\n') : '', eolCount: text ? text.length - 1 : 0, firstLineLength: text ? text[0].length : 0, lastLineLength: text ? text[text.length - 1].length : 0, diff --git a/src/vs/editor/test/common/model/modelEditOperation.test.ts b/src/vs/editor/test/common/model/modelEditOperation.test.ts index 2fc1337cbe2..1c6cc88081b 100644 --- a/src/vs/editor/test/common/model/modelEditOperation.test.ts +++ b/src/vs/editor/test/common/model/modelEditOperation.test.ts @@ -71,8 +71,8 @@ suite('Editor Model - Model Edit Operation', () => { identifier: edit.identifier, range: edit.range, text: edit.text, - forceMoveMarkers: edit.forceMoveMarkers, - isAutoWhitespaceEdit: edit.isAutoWhitespaceEdit + forceMoveMarkers: edit.forceMoveMarkers || false, + isAutoWhitespaceEdit: edit.isAutoWhitespaceEdit || false }; }; assert.deepEqual(originalOp.map(simplifyEdit), editOp.map(simplifyEdit)); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 08918576d0e..1223fd355ba 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -1552,14 +1552,9 @@ declare namespace monaco.editor { */ range: Range; /** - * The text to replace with. This can be null to emulate a simple delete. + * The text to replace with. This can be empty to emulate a simple delete. */ - text: string | null; - /** - * This indicates that this operation has "insert" semantics. - * i.e. forceMoveMarkers = true => if `range` is collapsed, all markers at the position will be moved. - */ - forceMoveMarkers: boolean; + text: string; } /** -- GitLab