提交 5507f635 编写于 作者: A Alex Dima

Move RawContentChange events creation to TextModel

上级 27f7c0bc
......@@ -12,7 +12,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
import { Position, IPosition } from 'vs/editor/common/core/position';
import { Range, IRange } from 'vs/editor/common/core/range';
import { Selection } from 'vs/editor/common/core/selection';
import { ModelRawContentChangedEvent, IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelOptionsChangedEvent, IModelLanguageConfigurationChangedEvent, IModelTokensChangedEvent, IModelContentChange, ModelRawChange } from 'vs/editor/common/model/textModelEvents';
import { ModelRawContentChangedEvent, IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelOptionsChangedEvent, IModelLanguageConfigurationChangedEvent, IModelTokensChangedEvent, IModelContentChange } from 'vs/editor/common/model/textModelEvents';
import { ThemeColor } from 'vs/platform/theme/common/themeService';
/**
......@@ -1098,7 +1098,6 @@ export class ApplyEditsResult {
constructor(
public readonly reverseEdits: IIdentifiedSingleEditOperation[],
public readonly rawChanges: ModelRawChange[],
public readonly changes: IInternalModelContentChange[],
public readonly trimAutoWhitespaceLineNumbers: number[]
) { }
......
......@@ -9,7 +9,6 @@ import { Position } from 'vs/editor/common/core/position';
import * as strings from 'vs/base/common/strings';
import * as arrays from 'vs/base/common/arrays';
import { PrefixSumComputer } from 'vs/editor/common/viewModel/prefixSumComputer';
import { ModelRawChange, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted } from 'vs/editor/common/model/textModelEvents';
import { ISingleEditOperationIdentifier, IIdentifiedSingleEditOperation, EndOfLinePreference, ITextBuffer, ApplyEditsResult, IInternalModelContentChange } from 'vs/editor/common/model';
export interface IValidatedEditOperation {
......@@ -252,7 +251,7 @@ export class LinesTextBuffer implements ITextBuffer {
public applyEdits(rawOperations: IIdentifiedSingleEditOperation[], recordTrimAutoWhitespace: boolean): ApplyEditsResult {
if (rawOperations.length === 0) {
return new ApplyEditsResult([], [], [], []);
return new ApplyEditsResult([], [], []);
}
let mightContainRTL = this._mightContainRTL;
......@@ -341,7 +340,7 @@ export class LinesTextBuffer implements ITextBuffer {
this._mightContainRTL = mightContainRTL;
this._mightContainNonBasicASCII = mightContainNonBasicASCII;
const [rawContentChanges, contentChanges] = this._doApplyEdits(operations);
const contentChanges = this._doApplyEdits(operations);
let trimAutoWhitespaceLineNumbers: number[] = null;
if (recordTrimAutoWhitespace && newTrimAutoWhitespaceCandidates.length > 0) {
......@@ -369,7 +368,6 @@ export class LinesTextBuffer implements ITextBuffer {
return new ApplyEditsResult(
reverseOperations,
rawContentChanges,
contentChanges,
trimAutoWhitespaceLineNumbers
);
......@@ -451,18 +449,16 @@ export class LinesTextBuffer implements ITextBuffer {
};
}
private _setLineContent(lineNumber: number, content: string, rawContentChanges: ModelRawChange[]): void {
private _setLineContent(lineNumber: number, content: string): void {
this._lines[lineNumber - 1] = content;
this._lineStarts.changeValue(lineNumber - 1, content.length + this._EOL.length);
rawContentChanges.push(new ModelRawLineChanged(lineNumber, content));
}
private _doApplyEdits(operations: IValidatedEditOperation[]): [ModelRawChange[], IInternalModelContentChange[]] {
private _doApplyEdits(operations: IValidatedEditOperation[]): IInternalModelContentChange[] {
// Sort operations descending
operations.sort(LinesTextBuffer._sortOpsDescending);
let rawContentChanges: ModelRawChange[] = [];
let contentChanges: IInternalModelContentChange[] = [];
for (let i = 0, len = operations.length; i < len; i++) {
......@@ -497,7 +493,7 @@ export class LinesTextBuffer implements ITextBuffer {
);
}
this._setLineContent(editLineNumber, editText, rawContentChanges);
this._setLineContent(editLineNumber, editText);
}
if (editingLinesCnt < deletingLinesCnt) {
......@@ -507,12 +503,10 @@ export class LinesTextBuffer implements ITextBuffer {
const endLineRemains = this._lines[endLineNumber - 1].substring(endColumn - 1);
// Reconstruct first line
this._setLineContent(spliceStartLineNumber, this._lines[spliceStartLineNumber - 1] + endLineRemains, rawContentChanges);
this._setLineContent(spliceStartLineNumber, this._lines[spliceStartLineNumber - 1] + endLineRemains);
this._lines.splice(spliceStartLineNumber, endLineNumber - spliceStartLineNumber);
this._lineStarts.removeValues(spliceStartLineNumber, endLineNumber - spliceStartLineNumber);
rawContentChanges.push(new ModelRawLinesDeleted(spliceStartLineNumber + 1, endLineNumber));
}
if (editingLinesCnt < insertingLinesCnt) {
......@@ -527,7 +521,7 @@ export class LinesTextBuffer implements ITextBuffer {
// Split last line
const leftoverLine = this._lines[spliceLineNumber - 1].substring(spliceColumn - 1);
this._setLineContent(spliceLineNumber, this._lines[spliceLineNumber - 1].substring(0, spliceColumn - 1), rawContentChanges);
this._setLineContent(spliceLineNumber, this._lines[spliceLineNumber - 1].substring(0, spliceColumn - 1));
// Lines in the middle
let newLines: string[] = new Array<string>(insertingLinesCnt - editingLinesCnt);
......@@ -540,8 +534,6 @@ export class LinesTextBuffer implements ITextBuffer {
newLinesLengths[newLines.length - 1] += leftoverLine.length;
this._lines = arrays.arrayInsert(this._lines, startLineNumber + editingLinesCnt, newLines);
this._lineStarts.insertValues(startLineNumber + editingLinesCnt, newLinesLengths);
rawContentChanges.push(new ModelRawLinesInserted(spliceLineNumber + 1, startLineNumber + insertingLinesCnt, newLines));
}
const contentChangeRange = new Range(startLineNumber, startColumn, endLineNumber, endColumn);
......@@ -556,7 +548,7 @@ export class LinesTextBuffer implements ITextBuffer {
});
}
return [rawContentChanges, contentChanges];
return contentChanges;
}
/**
......
......@@ -11,7 +11,7 @@ import { LanguageIdentifier, TokenizationRegistry, LanguageId } from 'vs/editor/
import { EditStack } from 'vs/editor/common/model/editStack';
import { Range, IRange } from 'vs/editor/common/core/range';
import { Selection } from 'vs/editor/common/core/selection';
import { ModelRawContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelTokensChangedEvent, IModelOptionsChangedEvent, IModelContentChangedEvent, InternalModelContentChangeEvent, ModelRawFlush, ModelRawEOLChanged } from 'vs/editor/common/model/textModelEvents';
import { ModelRawContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelTokensChangedEvent, IModelOptionsChangedEvent, IModelContentChangedEvent, InternalModelContentChangeEvent, ModelRawFlush, ModelRawEOLChanged, ModelRawChange, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted } from 'vs/editor/common/model/textModelEvents';
import { onUnexpectedError } from 'vs/base/common/errors';
import { IMarkdownString } from 'vs/base/common/htmlContent';
import * as strings from 'vs/base/common/strings';
......@@ -1033,21 +1033,83 @@ export class TextModel extends Disposable implements model.ITextModel {
}
}
private static _eolCount(text: string): number {
let eolCount = 0;
for (let i = 0, len = text.length; i < len; i++) {
const chr = text.charCodeAt(i);
if (chr === CharCode.CarriageReturn) {
eolCount++;
if (i + 1 < len && text.charCodeAt(i + 1) === CharCode.LineFeed) {
// \r\n... case
i++; // skip \n
} else {
// \r... case
}
} else if (chr === CharCode.LineFeed) {
eolCount++;
}
}
return eolCount;
}
private _applyEdits(rawOperations: model.IIdentifiedSingleEditOperation[]): model.IIdentifiedSingleEditOperation[] {
for (let i = 0, len = rawOperations.length; i < len; i++) {
rawOperations[i].range = this.validateRange(rawOperations[i].range);
}
const oldLineCount = this._buffer.getLineCount();
const result = this._buffer.applyEdits(rawOperations, this._options.trimAutoWhitespace);
const rawContentChanges = result.rawChanges;
const newLineCount = this._buffer.getLineCount();
const contentChanges = result.changes;
this._trimAutoWhitespaceLines = result.trimAutoWhitespaceLineNumbers;
if (rawContentChanges.length !== 0 || contentChanges.length !== 0) {
if (contentChanges.length !== 0) {
let rawContentChanges: ModelRawChange[] = [];
let lineCount = oldLineCount;
for (let i = 0, len = contentChanges.length; i < len; i++) {
const contentChange = contentChanges[i];
this._tokens.applyEdits(contentChange.range, contentChange.lines);
const change = contentChanges[i];
this._tokens.applyEdits(change.range, change.lines);
this._onDidChangeDecorations.fire();
this._decorationsTree.acceptReplace(contentChange.rangeOffset, contentChange.rangeLength, contentChange.text.length, contentChange.forceMoveMarkers);
this._decorationsTree.acceptReplace(change.rangeOffset, change.rangeLength, change.text.length, change.forceMoveMarkers);
const startLineNumber = change.range.startLineNumber;
const endLineNumber = change.range.endLineNumber;
const deletingLinesCnt = endLineNumber - startLineNumber;
const insertingLinesCnt = TextModel._eolCount(change.text);
const editingLinesCnt = Math.min(deletingLinesCnt, insertingLinesCnt);
const changeLineCountDelta = (insertingLinesCnt - deletingLinesCnt);
for (let j = editingLinesCnt; j >= 0; j--) {
const editLineNumber = startLineNumber + j;
const currentEditLineNumber = newLineCount - lineCount - changeLineCountDelta + editLineNumber;
rawContentChanges.push(new ModelRawLineChanged(editLineNumber, this.getLineContent(currentEditLineNumber)));
}
if (editingLinesCnt < deletingLinesCnt) {
// Must delete some lines
const spliceStartLineNumber = startLineNumber + editingLinesCnt;
rawContentChanges.push(new ModelRawLinesDeleted(spliceStartLineNumber + 1, endLineNumber));
}
if (editingLinesCnt < insertingLinesCnt) {
// Must insert some lines
const spliceLineNumber = startLineNumber + editingLinesCnt;
const cnt = insertingLinesCnt - editingLinesCnt;
const fromLineNumber = newLineCount - lineCount - cnt + spliceLineNumber + 1;
let newLines: string[] = [];
for (let i = 0; i < cnt; i++) {
let lineNumber = fromLineNumber + i;
newLines[lineNumber - fromLineNumber] = this.getLineContent(lineNumber);
}
rawContentChanges.push(new ModelRawLinesInserted(spliceLineNumber + 1, startLineNumber + insertingLinesCnt, newLines));
}
lineCount += changeLineCountDelta;
}
this._increaseVersionId();
......
......@@ -403,6 +403,7 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
insertPrefixSumValues[i] = outputLineCount;
}
// TODO@Alex: use arrays.arrayInsert
this.lines = this.lines.slice(0, fromLineNumber - 1).concat(insertLines).concat(this.lines.slice(fromLineNumber - 1));
this.prefixSumComputer.insertValues(fromLineNumber - 1, insertPrefixSumValues);
......
......@@ -129,7 +129,6 @@ suite('Editor Model - Model', () => {
thisModel.applyEdits([EditOperation.insert(new Position(1, 3), ' new line\nNo longer')]);
assert.deepEqual(e, new ModelRawContentChangedEvent(
[
new ModelRawLineChanged(1, 'My new line First Line'),
new ModelRawLineChanged(1, 'My new line'),
new ModelRawLinesInserted(2, 2, ['No longer First Line']),
],
......@@ -245,7 +244,6 @@ suite('Editor Model - Model', () => {
thisModel.applyEdits([EditOperation.delete(new Range(1, 4, 2, 6))]);
assert.deepEqual(e, new ModelRawContentChangedEvent(
[
new ModelRawLineChanged(1, 'My '),
new ModelRawLineChanged(1, 'My Second Line'),
new ModelRawLinesDeleted(2, 2),
],
......@@ -266,7 +264,6 @@ suite('Editor Model - Model', () => {
thisModel.applyEdits([EditOperation.delete(new Range(1, 4, 3, 5))]);
assert.deepEqual(e, new ModelRawContentChangedEvent(
[
new ModelRawLineChanged(1, 'My '),
new ModelRawLineChanged(1, 'My Third Line'),
new ModelRawLinesDeleted(2, 3),
],
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册