@@ -12,15 +12,8 @@ import {ILineEdit, ILineMarker, ModelLine} from 'vs/editor/common/model/modelLin
1212import { DeferredEventsBuilder , TextModelWithDecorations } from 'vs/editor/common/model/textModelWithDecorations' ;
1313import { IMode } from 'vs/editor/common/modes' ;
1414
15- export interface IDeltaSingleEditOperation {
16- original : IValidatedEditOperation ;
17- deltaStartLineNumber : number ;
18- deltaStartColumn : number ;
19- deltaEndLineNumber : number ;
20- deltaEndColumn : number ;
21- }
22-
2315export interface IValidatedEditOperation {
16+ sortIndex : number ;
2417 identifier : editorCommon . ISingleEditOperationIdentifier ;
2518 range : editorCommon . IEditorRange ;
2619 rangeLength : number ;
@@ -155,6 +148,7 @@ export class EditableTextModel extends TextModelWithDecorations implements edito
155148 }
156149
157150 return {
151+ sortIndex : 0 ,
158152 identifier : operations [ 0 ] . identifier ,
159153 range : entireEditRange ,
160154 rangeLength : this . getValueLengthInRange ( entireEditRange ) ,
@@ -163,6 +157,22 @@ export class EditableTextModel extends TextModelWithDecorations implements edito
163157 } ;
164158 }
165159
160+ private static _sortOpsAscending ( a :IValidatedEditOperation , b :IValidatedEditOperation ) : number {
161+ let r = Range . compareRangesUsingEnds ( a . range , b . range ) ;
162+ if ( r === 0 ) {
163+ return a . sortIndex - b . sortIndex ;
164+ }
165+ return r ;
166+ }
167+
168+ private static _sortOpsDescending ( a :IValidatedEditOperation , b :IValidatedEditOperation ) : number {
169+ let r = Range . compareRangesUsingEnds ( a . range , b . range ) ;
170+ if ( r === 0 ) {
171+ return b . sortIndex - a . sortIndex ;
172+ }
173+ return - r ;
174+ }
175+
166176 public applyEdits ( rawOperations :editorCommon . IIdentifiedSingleEditOperation [ ] ) : editorCommon . IIdentifiedSingleEditOperation [ ] {
167177 if ( rawOperations . length === 0 ) {
168178 return [ ] ;
@@ -173,6 +183,7 @@ export class EditableTextModel extends TextModelWithDecorations implements edito
173183 let op = rawOperations [ i ] ;
174184 let validatedRange = this . validateRange ( op . range ) ;
175185 operations [ i ] = {
186+ sortIndex : i ,
176187 identifier : op . identifier ,
177188 range : validatedRange ,
178189 rangeLength : this . getValueLengthInRange ( validatedRange ) ,
@@ -181,20 +192,19 @@ export class EditableTextModel extends TextModelWithDecorations implements edito
181192 } ;
182193 }
183194
184- // Sort operations
185- operations . sort ( ( a , b ) => {
186- return Range . compareRangesUsingEnds ( a . range , b . range ) ;
187- } ) ;
195+ // Sort operations ascending
196+ operations . sort ( EditableTextModel . _sortOpsAscending ) ;
197+
198+ for ( let i = 0 , count = operations . length - 1 ; i < count ; i ++ ) {
199+ let rangeEnd = operations [ i ] . range . getEndPosition ( ) ;
200+ let nextRangeStart = operations [ i + 1 ] . range . getStartPosition ( ) ;
188201
189- // Operations can not overlap!
190- for ( let i = operations . length - 2 ; i >= 0 ; i -- ) {
191- if ( operations [ i + 1 ] . range . getStartPosition ( ) . isBeforeOrEqual ( operations [ i ] . range . getEndPosition ( ) ) ) {
202+ if ( nextRangeStart . isBefore ( rangeEnd ) ) {
203+ // overlapping ranges
192204 throw new Error ( 'Overlapping ranges are not allowed!' ) ;
193205 }
194206 }
195207
196- // console.log(JSON.stringify(operations, null, '\t'));
197-
198208 operations = this . _reduceOperations ( operations ) ;
199209
200210 let editableRange = this . getEditableRange ( ) ;
@@ -208,8 +218,7 @@ export class EditableTextModel extends TextModelWithDecorations implements edito
208218 }
209219
210220 // Delta encode operations
211- let deltaOperations = EditableTextModel . _toDeltaOperations ( operations ) ;
212- let reverseRanges = EditableTextModel . _getInverseEditRanges ( deltaOperations ) ;
221+ let reverseRanges = EditableTextModel . _getInverseEditRanges ( operations ) ;
213222 let reverseOperations : editorCommon . IIdentifiedSingleEditOperation [ ] = [ ] ;
214223 for ( let i = 0 ; i < operations . length ; i ++ ) {
215224 reverseOperations [ i ] = {
@@ -225,63 +234,69 @@ export class EditableTextModel extends TextModelWithDecorations implements edito
225234 return reverseOperations ;
226235 }
227236
228- private static _toDeltaOperation ( base : IValidatedEditOperation , operation :IValidatedEditOperation ) : IDeltaSingleEditOperation {
229- let deltaStartLineNumber = operation . range . startLineNumber - ( base ? base . range . endLineNumber : 0 ) ;
230- let deltaStartColumn = operation . range . startColumn - ( deltaStartLineNumber === 0 ? base . range . endColumn : 0 ) ;
231- let deltaEndLineNumber = operation . range . endLineNumber - ( base ? base . range . endLineNumber : 0 ) ;
232- let deltaEndColumn = operation . range . endColumn - ( deltaEndLineNumber === 0 ? base . range . endColumn : 0 ) ;
233-
234- return {
235- original : operation ,
236- deltaStartLineNumber : deltaStartLineNumber ,
237- deltaStartColumn : deltaStartColumn ,
238- deltaEndLineNumber : deltaEndLineNumber ,
239- deltaEndColumn : deltaEndColumn
240- } ;
241- }
242-
243237 /**
244238 * Assumes `operations` are validated and sorted ascending
245239 */
246- public static _getInverseEditRanges ( operations :IDeltaSingleEditOperation [ ] ) : editorCommon . IEditorRange [ ] {
247- let lineNumber = 0 ,
248- column = 0 ,
249- result :editorCommon . IEditorRange [ ] = [ ] ;
240+ public static _getInverseEditRanges ( operations :IValidatedEditOperation [ ] ) : editorCommon . IEditorRange [ ] {
241+ let result :editorCommon . IEditorRange [ ] = [ ] ;
250242
243+ let prevOpEndLineNumber : number ;
244+ let prevOpEndColumn : number ;
245+ let prevOp :IValidatedEditOperation = null ;
251246 for ( let i = 0 , len = operations . length ; i < len ; i ++ ) {
252247 let op = operations [ i ] ;
253248
254- let startLineNumber = op . deltaStartLineNumber + lineNumber ;
255- let startColumn = op . deltaStartColumn + ( op . deltaStartLineNumber === 0 ? column : 0 ) ;
249+ let startLineNumber : number ;
250+ let startColumn : number ;
251+
252+ if ( prevOp ) {
253+ if ( prevOp . range . endLineNumber === op . range . startLineNumber ) {
254+ startLineNumber = prevOpEndLineNumber ;
255+ startColumn = prevOpEndColumn + ( op . range . startColumn - prevOp . range . endColumn ) ;
256+ } else {
257+ startLineNumber = prevOpEndLineNumber + ( op . range . startLineNumber - prevOp . range . endLineNumber ) ;
258+ startColumn = op . range . startColumn ;
259+ }
260+ } else {
261+ startLineNumber = op . range . startLineNumber ;
262+ startColumn = op . range . startColumn ;
263+ }
264+
256265 let resultRange : editorCommon . IEditorRange ;
257266
258- if ( op . original . lines && op . original . lines . length > 0 ) {
259- // There is something to insert
260- if ( op . original . lines . length === 1 ) {
261- // Single line insert
262- resultRange = new Range ( startLineNumber , startColumn , startLineNumber , startColumn + op . original . lines [ 0 ] . length ) ;
267+ if ( op . lines && op . lines . length > 0 ) {
268+ // the operation inserts something
269+ let lineCount = op . lines . length ;
270+ let firstLine = op . lines [ 0 ] ;
271+ let lastLine = op . lines [ lineCount - 1 ] ;
272+
273+ if ( lineCount === 1 ) {
274+ // single line insert
275+ resultRange = new Range ( startLineNumber , startColumn , startLineNumber , startColumn + firstLine . length ) ;
263276 } else {
264- // Multi line insert
265- resultRange = new Range ( startLineNumber , startColumn , startLineNumber + op . original . lines . length - 1 , op . original . lines [ op . original . lines . length - 1 ] . length + 1 ) ;
277+ // multi line insert
278+ resultRange = new Range ( startLineNumber , startColumn , startLineNumber + lineCount - 1 , lastLine . length + 1 ) ;
266279 }
267280 } else {
268281 // There is nothing to insert
269282 resultRange = new Range ( startLineNumber , startColumn , startLineNumber , startColumn ) ;
270283 }
271284
272- lineNumber = resultRange . endLineNumber ;
273- column = resultRange . endColumn ;
285+ prevOpEndLineNumber = resultRange . endLineNumber ;
286+ prevOpEndColumn = resultRange . endColumn ;
274287
275288 result . push ( resultRange ) ;
289+ prevOp = op ;
276290 }
277291
278292 return result ;
279293 }
280294
281295 private _applyEdits ( operations :IValidatedEditOperation [ ] ) : void {
282296
283- // Note the minus!
284- operations = operations . sort ( ( a , b ) => - Range . compareRangesUsingEnds ( a . range , b . range ) ) ;
297+ // Sort operations descending
298+ operations . sort ( EditableTextModel . _sortOpsDescending ) ;
299+
285300
286301 this . _withDeferredEvents ( ( deferredEventsBuilder :DeferredEventsBuilder ) => {
287302 let contentChangedEvents : editorCommon . IModelContentChangedEvent [ ] = [ ] ;
@@ -516,14 +531,6 @@ export class EditableTextModel extends TextModelWithDecorations implements edito
516531 }
517532 }
518533
519- public static _toDeltaOperations ( operations :IValidatedEditOperation [ ] ) : IDeltaSingleEditOperation [ ] {
520- let result : IDeltaSingleEditOperation [ ] = [ ] ;
521- for ( let i = 0 ; i < operations . length ; i ++ ) {
522- result [ i ] = EditableTextModel . _toDeltaOperation ( i > 0 ? operations [ i - 1 ] : null , operations [ i ] ) ;
523- }
524- return result ;
525- }
526-
527534 public undo ( ) : editorCommon . IEditorSelection [ ] {
528535 if ( this . _isDisposed ) {
529536 throw new Error ( 'EditableTextModel.undo: Model is disposed' ) ;
0 commit comments