@@ -114,35 +114,44 @@ public override Task<Script> InsertWithCursor(string operation, InsertPosition d
114114 }
115115 break ;
116116 }
117- operationsRunning ++ ;
118117 InsertWithCursorOnLayer ( this , layer , tcs , nodes , editor . Document ) ;
119118 return tcs . Task ;
120119 }
121120
122121 void InsertWithCursorOnLayer ( EditorScript currentScript , InsertionCursorLayer layer , TaskCompletionSource < Script > tcs , IList < AstNode > nodes , IDocument target )
123122 {
123+ var doc = target as TextDocument ;
124+ var op = new UndoOperation ( layer , tcs ) ;
125+ if ( doc != null ) {
126+ doc . UndoStack . Push ( op ) ;
127+ }
124128 layer . Exited += delegate ( object s , InsertionCursorEventArgs args ) {
125- if ( args . Success ) {
126- if ( args . InsertionPoint . LineAfter == NewLineInsertion . None &&
127- args . InsertionPoint . LineBefore == NewLineInsertion . None && nodes . Count > 1 ) {
128- args . InsertionPoint . LineAfter = NewLineInsertion . BlankLine ;
129- }
130- foreach ( var node in nodes . Reverse ( ) ) {
131- int indentLevel = currentScript . GetIndentLevelAt ( target . GetOffset ( args . InsertionPoint . Location ) ) ;
132- var output = currentScript . OutputNode ( indentLevel , node ) ;
133- var offset = target . GetOffset ( args . InsertionPoint . Location ) ;
134- var delta = args . InsertionPoint . Insert ( target , output . Text ) ;
135- output . RegisterTrackedSegments ( currentScript , delta + offset ) ;
129+ doc . UndoStack . StartContinuedUndoGroup ( ) ;
130+ try {
131+ if ( args . Success ) {
132+ if ( args . InsertionPoint . LineAfter == NewLineInsertion . None &&
133+ args . InsertionPoint . LineBefore == NewLineInsertion . None && nodes . Count > 1 ) {
134+ args . InsertionPoint . LineAfter = NewLineInsertion . BlankLine ;
135+ }
136+ foreach ( var node in nodes . Reverse ( ) ) {
137+ int indentLevel = currentScript . GetIndentLevelAt ( target . GetOffset ( args . InsertionPoint . Location ) ) ;
138+ var output = currentScript . OutputNode ( indentLevel , node ) ;
139+ var offset = target . GetOffset ( args . InsertionPoint . Location ) ;
140+ var delta = args . InsertionPoint . Insert ( target , output . Text ) ;
141+ output . RegisterTrackedSegments ( currentScript , delta + offset ) ;
142+ }
143+ tcs . SetResult ( currentScript ) ;
136144 }
137- tcs . SetResult ( currentScript ) ;
145+ layer . Dispose ( ) ;
146+ DisposeOnClose ( ) ;
147+ } finally {
148+ doc . UndoStack . EndUndoGroup ( ) ;
138149 }
139- layer . Dispose ( ) ;
140- DisposeOnClose ( ) ;
150+ op . Reset ( ) ;
141151 } ;
142152 }
143153
144154 readonly List < Script > startedScripts = new List < Script > ( ) ;
145- int operationsRunning ;
146155
147156 public override Task < Script > InsertWithCursor ( string operation , ITypeDefinition parentType , Func < Script , RefactoringContext , IList < AstNode > > nodeCallback )
148157 {
@@ -195,7 +204,6 @@ public override Task<Script> InsertWithCursor(string operation, ITypeDefinition
195204 tcs . SetResult ( script ) ;
196205 return tcs . Task ;
197206 }
198- operationsRunning ++ ;
199207 InsertWithCursorOnLayer ( script , layer , tcs , nodes , area . Document ) ;
200208 return tcs . Task ;
201209 }
@@ -205,14 +213,10 @@ void DisposeOnClose(bool force = false)
205213 {
206214 if ( isDisposed )
207215 return ;
208- if ( force )
209- operationsRunning = 0 ;
210- if ( operationsRunning -- == 0 ) {
211- isDisposed = true ;
212- base . Dispose ( ) ;
213- // refresh parse information so that the issue can disappear immediately
214- SD . ParserService . ParseAsync ( editor . FileName , editor . Document ) . FireAndForget ( ) ;
215- }
216+ isDisposed = true ;
217+ base . Dispose ( ) ;
218+ // refresh parse information so that the issue can disappear immediately
219+ SD . ParserService . ParseAsync ( editor . FileName , editor . Document ) . FireAndForget ( ) ;
216220 foreach ( var script in startedScripts )
217221 script . Dispose ( ) ;
218222 }
@@ -221,7 +225,38 @@ public override void Dispose()
221225 {
222226 DisposeOnClose ( ) ;
223227 }
224-
228+
229+ class UndoOperation : IUndoableOperation
230+ {
231+ InsertionCursorLayer layer ;
232+ TaskCompletionSource < Script > tcs ;
233+
234+ public UndoOperation ( InsertionCursorLayer layer , TaskCompletionSource < Script > tcs )
235+ {
236+ this . layer = layer ;
237+ this . tcs = tcs ;
238+ }
239+
240+ public void Reset ( )
241+ {
242+ layer = null ;
243+ tcs = null ;
244+ }
245+
246+ public void Undo ( )
247+ {
248+ if ( layer != null )
249+ layer . Dispose ( ) ;
250+ layer = null ;
251+ if ( tcs != null )
252+ tcs . SetCanceled ( ) ;
253+ tcs = null ;
254+ }
255+
256+ public void Redo ( )
257+ {
258+ }
259+ }
225260 }
226261
227262 class InsertionCursorLayer : UIElement , IDisposable
0 commit comments