From 7eff5d6d85f7352ffd7e2ea79f10aceca41aa1ef Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 19 Jan 2018 12:32:20 +0100 Subject: [PATCH] Simplify edits handling in TextModelTokens --- src/vs/editor/common/model.ts | 1 - .../chunksTextBuffer/chunksTextBuffer.ts | 1 - .../model/linesTextBuffer/linesTextBuffer.ts | 1 - .../pieceTreeTextBuffer.ts | 1 - src/vs/editor/common/model/textModel.ts | 19 ++++++++-- src/vs/editor/common/model/textModelTokens.ts | 38 ++++++------------- 6 files changed, 26 insertions(+), 35 deletions(-) diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index a84ce2a5bca..31f7b8be668 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -1120,7 +1120,6 @@ export class ApplyEditsResult { */ export interface IInternalModelContentChange extends IModelContentChange { range: Range; - lines: string[]; rangeOffset: number; forceMoveMarkers: boolean; } diff --git a/src/vs/editor/common/model/chunksTextBuffer/chunksTextBuffer.ts b/src/vs/editor/common/model/chunksTextBuffer/chunksTextBuffer.ts index d089cd00af0..046f3387ea5 100644 --- a/src/vs/editor/common/model/chunksTextBuffer/chunksTextBuffer.ts +++ b/src/vs/editor/common/model/chunksTextBuffer/chunksTextBuffer.ts @@ -412,7 +412,6 @@ export class ChunksTextBuffer implements ITextBuffer { range: op.range, rangeLength: op.rangeLength, text: text, - lines: op.lines, rangeOffset: op.rangeOffset, forceMoveMarkers: op.forceMoveMarkers }); diff --git a/src/vs/editor/common/model/linesTextBuffer/linesTextBuffer.ts b/src/vs/editor/common/model/linesTextBuffer/linesTextBuffer.ts index 3121969026a..0d03ecd90a0 100644 --- a/src/vs/editor/common/model/linesTextBuffer/linesTextBuffer.ts +++ b/src/vs/editor/common/model/linesTextBuffer/linesTextBuffer.ts @@ -590,7 +590,6 @@ export class LinesTextBuffer implements ITextBuffer { range: contentChangeRange, rangeLength: op.rangeLength, text: text, - lines: op.lines, rangeOffset: op.rangeOffset, forceMoveMarkers: op.forceMoveMarkers }); diff --git a/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts index baaf505f6d0..f8505567923 100644 --- a/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts +++ b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts @@ -413,7 +413,6 @@ export class PieceTreeTextBuffer implements ITextBuffer { range: contentChangeRange, rangeLength: op.rangeLength, text: text, - lines: op.lines, rangeOffset: op.rangeOffset, forceMoveMarkers: op.forceMoveMarkers }); diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index fc3139a558d..90e95ac7bb7 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -1096,12 +1096,16 @@ export class TextModel extends Disposable implements model.ITextModel { } } - private static _eolCount(text: string): number { + private static _eolCount(text: string): [number, number] { let eolCount = 0; + let firstLineLength = 0; for (let i = 0, len = text.length; i < len; i++) { const chr = text.charCodeAt(i); if (chr === CharCode.CarriageReturn) { + if (eolCount === 0) { + firstLineLength = i; + } eolCount++; if (i + 1 < len && text.charCodeAt(i + 1) === CharCode.LineFeed) { // \r\n... case @@ -1110,10 +1114,16 @@ export class TextModel extends Disposable implements model.ITextModel { // \r... case } } else if (chr === CharCode.LineFeed) { + if (eolCount === 0) { + firstLineLength = i; + } eolCount++; } } - return eolCount; + if (eolCount === 0) { + firstLineLength = text.length; + } + return [eolCount, firstLineLength]; } private _applyEdits(rawOperations: model.IIdentifiedSingleEditOperation[]): model.IIdentifiedSingleEditOperation[] { @@ -1134,7 +1144,8 @@ export class TextModel extends Disposable implements model.ITextModel { let lineCount = oldLineCount; for (let i = 0, len = contentChanges.length; i < len; i++) { const change = contentChanges[i]; - this._tokens.applyEdits(change.range, change.lines); + const [eolCount, firstLineLength] = TextModel._eolCount(change.text); + this._tokens.applyEdits(change.range, eolCount, firstLineLength); this._onDidChangeDecorations.fire(); this._decorationsTree.acceptReplace(change.rangeOffset, change.rangeLength, change.text.length, change.forceMoveMarkers); @@ -1142,7 +1153,7 @@ export class TextModel extends Disposable implements model.ITextModel { const endLineNumber = change.range.endLineNumber; const deletingLinesCnt = endLineNumber - startLineNumber; - const insertingLinesCnt = TextModel._eolCount(change.text); + const insertingLinesCnt = eolCount; const editingLinesCnt = Math.min(deletingLinesCnt, insertingLinesCnt); const changeLineCountDelta = (insertingLinesCnt - deletingLinesCnt); diff --git a/src/vs/editor/common/model/textModelTokens.ts b/src/vs/editor/common/model/textModelTokens.ts index e190d4337bb..bc0a715dda9 100644 --- a/src/vs/editor/common/model/textModelTokens.ts +++ b/src/vs/editor/common/model/textModelTokens.ts @@ -285,34 +285,18 @@ export class ModelLinesTokens { //#region Editing - // TODO: simplify - public applyEdits(range: Range, lines: string[]): void { + public applyEdits(range: Range, eolCount: number, firstLineLength: number): void { const deletingLinesCnt = range.endLineNumber - range.startLineNumber; - const insertingLinesCnt = (lines ? lines.length - 1 : 0); + const insertingLinesCnt = eolCount; const editingLinesCnt = Math.min(deletingLinesCnt, insertingLinesCnt); - // Iterating descending to overlap with previous op - // in case there are common lines being edited in both for (let j = editingLinesCnt; j >= 0; j--) { - const editLineNumber = range.startLineNumber + j; - this.invalidateLine(editLineNumber - 1); - } - - if (editingLinesCnt < deletingLinesCnt) { - // Must delete some lines - const spliceStartLineNumber = range.startLineNumber + editingLinesCnt; - this.invalidateLine(spliceStartLineNumber - 1); - } - - if (editingLinesCnt < insertingLinesCnt) { - // Must insert some lines - const spliceLineNumber = range.startLineNumber + editingLinesCnt; - this.invalidateLine(spliceLineNumber - 1); + this.invalidateLine(range.startLineNumber + j - 1); } this._acceptDeleteRange(range); - this._acceptInsertText(new Position(range.startLineNumber, range.startColumn), lines); + this._acceptInsertText(new Position(range.startLineNumber, range.startColumn), eolCount, firstLineLength); } private _acceptDeleteRange(range: Range): void { @@ -350,9 +334,9 @@ export class ModelLinesTokens { this._tokens.splice(range.startLineNumber, range.endLineNumber - range.startLineNumber); } - private _acceptInsertText(position: Position, insertLines: string[]): void { + private _acceptInsertText(position: Position, eolCount: number, firstLineLength: number): void { - if (!insertLines || insertLines.length === 0) { + if (eolCount === 0 && firstLineLength === 0) { // Nothing to insert return; } @@ -362,18 +346,18 @@ export class ModelLinesTokens { return; } - if (insertLines.length === 1) { + if (eolCount === 0) { // Inserting text on one line - this._tokens[lineIndex].insert(position.column - 1, insertLines[0].length); + this._tokens[lineIndex].insert(position.column - 1, firstLineLength); return; } const line = this._tokens[lineIndex]; line.deleteEnding(position.column - 1); - line.insert(position.column - 1, insertLines[0].length); + line.insert(position.column - 1, firstLineLength); - let insert: ModelLineTokens[] = new Array(insertLines.length - 1); - for (let i = insertLines.length - 2; i >= 0; i--) { + let insert: ModelLineTokens[] = new Array(eolCount); + for (let i = eolCount - 1; i >= 0; i--) { insert[i] = new ModelLineTokens(null); } this._tokens = arrays.arrayInsert(this._tokens, position.lineNumber, insert);