Simplify edits handling in TextModelTokens

This commit is contained in:
Alex Dima
2018-01-19 12:32:20 +01:00
parent bbdd7f8118
commit 7eff5d6d85
6 changed files with 26 additions and 35 deletions
-1
View File
@@ -1120,7 +1120,6 @@ export class ApplyEditsResult {
*/
export interface IInternalModelContentChange extends IModelContentChange {
range: Range;
lines: string[];
rangeOffset: number;
forceMoveMarkers: boolean;
}
@@ -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
});
@@ -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
});
@@ -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
});
+15 -4
View File
@@ -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);
+11 -27
View File
@@ -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<ModelLineTokens>(insertLines.length - 1);
for (let i = insertLines.length - 2; i >= 0; i--) {
let insert: ModelLineTokens[] = new Array<ModelLineTokens>(eolCount);
for (let i = eolCount - 1; i >= 0; i--) {
insert[i] = new ModelLineTokens(null);
}
this._tokens = arrays.arrayInsert(this._tokens, position.lineNumber, insert);