mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-15 04:41:00 +01:00
Simplify edits handling in TextModelTokens
This commit is contained in:
@@ -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
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user