Skip to content

Commit d786468

Browse files
committed
refactor ExtHostDocumentModel to ready for node_module consumption
1 parent ffc2147 commit d786468

5 files changed

Lines changed: 201 additions & 181 deletions

File tree

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
'use strict';
6+
7+
import URI from 'vs/base/common/uri';
8+
import {IModelContentChangedEvent2, IRange, IPosition} from 'vs/editor/common/editorCommon';
9+
import {PrefixSumComputer} from 'vs/editor/common/viewModel/prefixSumComputer';
10+
11+
export class MirrorModel2 {
12+
13+
protected _uri: URI;
14+
protected _lines: string[];
15+
protected _eol: string;
16+
protected _versionId: number;
17+
protected _lineStarts: PrefixSumComputer;
18+
19+
constructor(uri: URI, lines: string[], eol: string, versionId: number) {
20+
this._uri = uri;
21+
this._lines = lines;
22+
this._eol = eol;
23+
this._versionId = versionId;
24+
}
25+
26+
dispose(): void {
27+
this._lines.length = 0;
28+
}
29+
30+
get version(): number {
31+
return this._versionId;
32+
}
33+
34+
getText(): string {
35+
return this._lines.join(this._eol);
36+
}
37+
38+
onEvents(events: IModelContentChangedEvent2[]): void {
39+
// Update my lines
40+
let lastVersionId = -1;
41+
for (let i = 0, len = events.length; i < len; i++) {
42+
let e = events[i];
43+
44+
this._acceptDeleteRange(e.range);
45+
this._acceptInsertText({
46+
lineNumber: e.range.startLineNumber,
47+
column: e.range.startColumn
48+
}, e.text);
49+
lastVersionId = Math.max(lastVersionId, e.versionId);
50+
}
51+
if (lastVersionId !== -1) {
52+
this._versionId = lastVersionId;
53+
}
54+
}
55+
56+
protected _ensureLineStarts(): void {
57+
if (!this._lineStarts) {
58+
const lineStartValues:number[] = [];
59+
const eolLength = this._eol.length;
60+
for (let i = 0, len = this._lines.length; i < len; i++) {
61+
lineStartValues.push(this._lines[i].length + eolLength);
62+
}
63+
this._lineStarts = new PrefixSumComputer(lineStartValues);
64+
}
65+
}
66+
67+
/**
68+
* All changes to a line's text go through this method
69+
*/
70+
private _setLineText(lineIndex:number, newValue:string): void {
71+
this._lines[lineIndex] = newValue;
72+
if (this._lineStarts) {
73+
// update prefix sum
74+
this._lineStarts.changeValue(lineIndex, this._lines[lineIndex].length + this._eol.length);
75+
}
76+
}
77+
78+
private _acceptDeleteRange(range: IRange): void {
79+
80+
if (range.startLineNumber === range.endLineNumber) {
81+
if (range.startColumn === range.endColumn) {
82+
// Nothing to delete
83+
return;
84+
}
85+
// Delete text on the affected line
86+
this._setLineText(range.startLineNumber - 1,
87+
this._lines[range.startLineNumber - 1].substring(0, range.startColumn - 1)
88+
+ this._lines[range.startLineNumber - 1].substring(range.endColumn - 1)
89+
);
90+
return;
91+
}
92+
93+
// Take remaining text on last line and append it to remaining text on first line
94+
this._setLineText(range.startLineNumber - 1,
95+
this._lines[range.startLineNumber - 1].substring(0, range.startColumn - 1)
96+
+ this._lines[range.endLineNumber - 1].substring(range.endColumn - 1)
97+
);
98+
99+
// Delete middle lines
100+
this._lines.splice(range.startLineNumber, range.endLineNumber - range.startLineNumber);
101+
if (this._lineStarts) {
102+
// update prefix sum
103+
this._lineStarts.removeValues(range.startLineNumber, range.endLineNumber - range.startLineNumber);
104+
}
105+
}
106+
107+
private _acceptInsertText(position: IPosition, insertText:string): void {
108+
if (insertText.length === 0) {
109+
// Nothing to insert
110+
return;
111+
}
112+
let insertLines = insertText.split(/\r\n|\r|\n/);
113+
if (insertLines.length === 1) {
114+
// Inserting text on one line
115+
this._setLineText(position.lineNumber - 1,
116+
this._lines[position.lineNumber - 1].substring(0, position.column - 1)
117+
+ insertLines[0]
118+
+ this._lines[position.lineNumber - 1].substring(position.column - 1)
119+
);
120+
return;
121+
}
122+
123+
// Append overflowing text from first line to the end of text to insert
124+
insertLines[insertLines.length - 1] += this._lines[position.lineNumber - 1].substring(position.column - 1);
125+
126+
// Delete overflowing text from first line and insert text on first line
127+
this._setLineText(position.lineNumber - 1,
128+
this._lines[position.lineNumber - 1].substring(0, position.column - 1)
129+
+ insertLines[0]
130+
);
131+
132+
// Insert new lines & store lengths
133+
let newLengths:number[] = new Array<number>(insertLines.length - 1);
134+
for (let i = 1; i < insertLines.length; i++) {
135+
this._lines.splice(position.lineNumber + i - 1, 0, insertLines[i]);
136+
newLengths[i - 1] = insertLines[i].length + this._eol.length;
137+
}
138+
139+
if (this._lineStarts) {
140+
// update prefix sum
141+
this._lineStarts.insertValues(position.lineNumber, newLengths);
142+
}
143+
}
144+
}

src/vs/editor/test/common/model/editableTextModel.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {EditableTextModel, IValidatedEditOperation} from 'vs/editor/common/model
1212
import {TextModel} from 'vs/editor/common/model/textModel';
1313
import {LineMarker, TextModelWithMarkers} from 'vs/editor/common/model/textModelWithMarkers';
1414
import {ILineMarker} from 'vs/editor/common/model/modelLine';
15-
import {ExtHostDocument} from 'vs/workbench/api/common/extHostDocuments';
15+
import {MirrorModel2} from 'vs/editor/common/model/mirrorModel2';
1616
import {MirrorModel, IMirrorModelEvents} from 'vs/editor/common/model/mirrorModel';
1717

1818
suite('EditorModel - EditableTextModel._getInverseEdits', () => {
@@ -1185,7 +1185,7 @@ suite('EditorModel - EditableTextModel.applyEdits', () => {
11851185
var mirrorModel1 = new MirrorModel(null, model.getVersionId(), model.toRawText(), null);
11861186
var mirrorModel1PrevVersionId = model.getVersionId();
11871187

1188-
var mirrorModel2 = new ExtHostDocument(null, null, model.toRawText().lines, model.toRawText().EOL, null, model.getVersionId(), false);
1188+
var mirrorModel2 = new MirrorModel2(null, model.toRawText().lines, model.toRawText().EOL, model.getVersionId());
11891189
var mirrorModel2PrevVersionId = model.getVersionId();
11901190

11911191
model.addListener(EditorCommon.EventType.ModelContentChanged, (e:EditorCommon.IModelContentChangedEvent) => {
@@ -1207,7 +1207,7 @@ suite('EditorModel - EditableTextModel.applyEdits', () => {
12071207
console.warn('Model version id did not advance between edits (2)');
12081208
}
12091209
mirrorModel2PrevVersionId = versionId;
1210-
mirrorModel2._acceptEvents([e]);
1210+
mirrorModel2.onEvents([e]);
12111211
});
12121212

12131213
var assertMirrorModels = () => {

0 commit comments

Comments
 (0)