@@ -12,18 +12,133 @@ import { IUndoRedoService, IResourceUndoRedoElement, UndoRedoElementType, IWorks
1212import { URI } from 'vs/base/common/uri' ;
1313import { getComparisonKey as uriGetComparisonKey } from 'vs/base/common/resources' ;
1414import { TextChange , compressConsecutiveTextChanges } from 'vs/editor/common/model/textChange' ;
15+ import * as buffer from 'vs/base/common/buffer' ;
16+
17+ class SingleModelEditStackData {
18+
19+ public static create ( model : ITextModel , beforeCursorState : Selection [ ] | null ) : SingleModelEditStackData {
20+ const alternativeVersionId = model . getAlternativeVersionId ( ) ;
21+ const eol = getModelEOL ( model ) ;
22+ return new SingleModelEditStackData (
23+ alternativeVersionId ,
24+ alternativeVersionId ,
25+ eol ,
26+ eol ,
27+ beforeCursorState ,
28+ beforeCursorState ,
29+ [ ]
30+ ) ;
31+ }
32+
33+ constructor (
34+ public readonly beforeVersionId : number ,
35+ public afterVersionId : number ,
36+ public readonly beforeEOL : EndOfLineSequence ,
37+ public afterEOL : EndOfLineSequence ,
38+ public readonly beforeCursorState : Selection [ ] | null ,
39+ public afterCursorState : Selection [ ] | null ,
40+ public changes : TextChange [ ]
41+ ) { }
42+
43+ public append ( model : ITextModel , operations : IValidEditOperation [ ] , afterEOL : EndOfLineSequence , afterVersionId : number , afterCursorState : Selection [ ] | null ) : void {
44+ if ( operations . length > 0 ) {
45+ this . changes = compressConsecutiveTextChanges ( this . changes , operations . map ( op => op . textChange ) ) ;
46+ }
47+ this . afterEOL = afterEOL ;
48+ this . afterVersionId = afterVersionId ;
49+ this . afterCursorState = afterCursorState ;
50+ }
51+
52+ private static _writeSelectionsSize ( selections : Selection [ ] | null ) : number {
53+ return 4 + 4 * 4 * ( selections ? selections . length : 0 ) ;
54+ }
55+
56+ private static _writeSelections ( b : Uint8Array , selections : Selection [ ] | null , offset : number ) : number {
57+ buffer . writeUInt32BE ( b , ( selections ? selections . length : 0 ) , offset ) ; offset += 4 ;
58+ if ( selections ) {
59+ for ( const selection of selections ) {
60+ buffer . writeUInt32BE ( b , selection . selectionStartLineNumber , offset ) ; offset += 4 ;
61+ buffer . writeUInt32BE ( b , selection . selectionStartColumn , offset ) ; offset += 4 ;
62+ buffer . writeUInt32BE ( b , selection . positionLineNumber , offset ) ; offset += 4 ;
63+ buffer . writeUInt32BE ( b , selection . positionColumn , offset ) ; offset += 4 ;
64+ }
65+ }
66+ return offset ;
67+ }
68+
69+ private static _readSelections ( b : Uint8Array , offset : number , dest : Selection [ ] ) : number {
70+ const count = buffer . readUInt32BE ( b , offset ) ; offset += 4 ;
71+ for ( let i = 0 ; i < count ; i ++ ) {
72+ const selectionStartLineNumber = buffer . readUInt32BE ( b , offset ) ; offset += 4 ;
73+ const selectionStartColumn = buffer . readUInt32BE ( b , offset ) ; offset += 4 ;
74+ const positionLineNumber = buffer . readUInt32BE ( b , offset ) ; offset += 4 ;
75+ const positionColumn = buffer . readUInt32BE ( b , offset ) ; offset += 4 ;
76+ dest . push ( new Selection ( selectionStartLineNumber , selectionStartColumn , positionLineNumber , positionColumn ) ) ;
77+ }
78+ return offset ;
79+ }
80+
81+ public serialize ( ) : ArrayBuffer {
82+ let necessarySize = (
83+ + 4 // beforeVersionId
84+ + 4 // afterVersionId
85+ + 1 // beforeEOL
86+ + 1 // afterEOL
87+ + SingleModelEditStackData . _writeSelectionsSize ( this . beforeCursorState )
88+ + SingleModelEditStackData . _writeSelectionsSize ( this . afterCursorState )
89+ + 4 // change count
90+ ) ;
91+ for ( const change of this . changes ) {
92+ necessarySize += change . writeSize ( ) ;
93+ }
94+
95+ const b = new Uint8Array ( necessarySize ) ;
96+ let offset = 0 ;
97+ buffer . writeUInt32BE ( b , this . beforeVersionId , offset ) ; offset += 4 ;
98+ buffer . writeUInt32BE ( b , this . afterVersionId , offset ) ; offset += 4 ;
99+ buffer . writeUInt8 ( b , this . beforeEOL , offset ) ; offset += 1 ;
100+ buffer . writeUInt8 ( b , this . afterEOL , offset ) ; offset += 1 ;
101+ offset = SingleModelEditStackData . _writeSelections ( b , this . beforeCursorState , offset ) ;
102+ offset = SingleModelEditStackData . _writeSelections ( b , this . afterCursorState , offset ) ;
103+ buffer . writeUInt32BE ( b , this . changes . length , offset ) ; offset += 4 ;
104+ for ( const change of this . changes ) {
105+ offset = change . write ( b , offset ) ;
106+ }
107+ return b . buffer ;
108+ }
109+
110+ public static deserialize ( source : ArrayBuffer ) : SingleModelEditStackData {
111+ const b = new Uint8Array ( source ) ;
112+ let offset = 0 ;
113+ const beforeVersionId = buffer . readUInt32BE ( b , offset ) ; offset += 4 ;
114+ const afterVersionId = buffer . readUInt32BE ( b , offset ) ; offset += 4 ;
115+ const beforeEOL = buffer . readUInt8 ( b , offset ) ; offset += 1 ;
116+ const afterEOL = buffer . readUInt8 ( b , offset ) ; offset += 1 ;
117+ const beforeCursorState : Selection [ ] = [ ] ;
118+ offset = SingleModelEditStackData . _readSelections ( b , offset , beforeCursorState ) ;
119+ const afterCursorState : Selection [ ] = [ ] ;
120+ offset = SingleModelEditStackData . _readSelections ( b , offset , afterCursorState ) ;
121+ const changeCount = buffer . readUInt32BE ( b , offset ) ; offset += 4 ;
122+ const changes : TextChange [ ] = [ ] ;
123+ for ( let i = 0 ; i < changeCount ; i ++ ) {
124+ offset = TextChange . read ( b , offset , changes ) ;
125+ }
126+ return new SingleModelEditStackData (
127+ beforeVersionId ,
128+ afterVersionId ,
129+ beforeEOL ,
130+ afterEOL ,
131+ beforeCursorState ,
132+ afterCursorState ,
133+ changes
134+ ) ;
135+ }
136+ }
15137
16138export class SingleModelEditStackElement implements IResourceUndoRedoElement {
17139
18- private _isOpen : boolean ;
19140 public model : ITextModel ;
20- private readonly _beforeVersionId : number ;
21- private readonly _beforeEOL : EndOfLineSequence ;
22- private readonly _beforeCursorState : Selection [ ] | null ;
23- private _afterVersionId : number ;
24- private _afterEOL : EndOfLineSequence ;
25- private _afterCursorState : Selection [ ] | null ;
26- private _changes : TextChange [ ] ;
141+ private _data : SingleModelEditStackData | ArrayBuffer ;
27142
28143 public get type ( ) : UndoRedoElementType . Resource {
29144 return UndoRedoElementType . Resource ;
@@ -38,45 +153,44 @@ export class SingleModelEditStackElement implements IResourceUndoRedoElement {
38153 }
39154
40155 constructor ( model : ITextModel , beforeCursorState : Selection [ ] | null ) {
41- this . _isOpen = true ;
42156 this . model = model ;
43- this . _beforeVersionId = this . model . getAlternativeVersionId ( ) ;
44- this . _beforeEOL = getModelEOL ( this . model ) ;
45- this . _beforeCursorState = beforeCursorState ;
46- this . _afterVersionId = this . _beforeVersionId ;
47- this . _afterEOL = this . _beforeEOL ;
48- this . _afterCursorState = this . _beforeCursorState ;
49- this . _changes = [ ] ;
157+ this . _data = SingleModelEditStackData . create ( model , beforeCursorState ) ;
50158 }
51159
52160 public setModel ( model : ITextModel ) : void {
53161 this . model = model ;
54162 }
55163
56164 public canAppend ( model : ITextModel ) : boolean {
57- return ( this . _isOpen && this . model === model ) ;
165+ return ( this . model === model && this . _data instanceof SingleModelEditStackData ) ;
58166 }
59167
60168 public append ( model : ITextModel , operations : IValidEditOperation [ ] , afterEOL : EndOfLineSequence , afterVersionId : number , afterCursorState : Selection [ ] | null ) : void {
61- if ( operations . length > 0 ) {
62- this . _changes = compressConsecutiveTextChanges ( this . _changes , operations . map ( op => op . textChange ) ) ;
169+ if ( this . _data instanceof SingleModelEditStackData ) {
170+ this . _data . append ( model , operations , afterEOL , afterVersionId , afterCursorState ) ;
63171 }
64- this . _afterEOL = afterEOL ;
65- this . _afterVersionId = afterVersionId ;
66- this . _afterCursorState = afterCursorState ;
67172 }
68173
69174 public close ( ) : void {
70- this . _isOpen = false ;
175+ if ( this . _data instanceof SingleModelEditStackData ) {
176+ this . _data = this . _data . serialize ( ) ;
177+ }
71178 }
72179
73180 public undo ( ) : void {
74- this . _isOpen = false ;
75- this . model . _applyUndo ( this . _changes , this . _beforeEOL , this . _beforeVersionId , this . _beforeCursorState ) ;
181+ if ( this . _data instanceof SingleModelEditStackData ) {
182+ this . _data = this . _data . serialize ( ) ;
183+ }
184+ const data = SingleModelEditStackData . deserialize ( this . _data ) ;
185+ this . model . _applyUndo ( data . changes , data . beforeEOL , data . beforeVersionId , data . beforeCursorState ) ;
76186 }
77187
78188 public redo ( ) : void {
79- this . model . _applyRedo ( this . _changes , this . _afterEOL , this . _afterVersionId , this . _afterCursorState ) ;
189+ if ( this . _data instanceof SingleModelEditStackData ) {
190+ this . _data = this . _data . serialize ( ) ;
191+ }
192+ const data = SingleModelEditStackData . deserialize ( this . _data ) ;
193+ this . model . _applyRedo ( data . changes , data . afterEOL , data . afterVersionId , data . afterCursorState ) ;
80194 }
81195}
82196
0 commit comments