/// <remarks> /// Edits are queued up by our TextBufferChanged handler and then we finally add them to the /// undo stack here in response to PostChanged. The reason and history behind why we do this /// is as follows: /// /// Originally this was done for VB commit, which uses undo events (i.e. TransactionCompleted) to /// trigger commit. Their commit logic relies on the buffer being in a state such that applying /// an edit synchronously raises a Changed event (which is always the case for PostChanged, but /// not for Changed if there are nested edits). /// /// JaredPar made a change (CS 1182244) that allowed VB to detect that UndoTransactionCompleted /// was being fired from a nested edit, and therefore delay the actual commit until the following /// PostChanged event. /// /// So this allowed us to move TextBufferUndoManager back to adding undo actions directly /// from the TextBufferChanged handler (CS 1285117). This is preferable, as otherwise there's a /// "delay" between when the edit happens and when we record the edit on the undo stack, /// allowing other people to stick something on the undo stack (i.e. from /// their ITextBuffer.Changed handler) in between. The result is actions being "out-of-order" /// on the undo stack. /// /// Unfortunately, it turns out VB snippets actually rely on this "out-of-order" behavior /// (see Dev10 834740) and so we are forced to revert CS 1285117) and return to the model /// where we queue up edits and delay adding them to the undo stack until PostChanged. /// /// It would be good to revisit this at again, but we would need to work with VB /// to fix their snippets / undo behavior, and verify that VB commit is also unaffected. /// </remarks> private void TextBufferPostChanged(object sender, EventArgs e) { // Only process a top level PostChanged event. Nested events will continue to process TextChange events // which are added to the queue and will be processed below if (_inPostChanged) { return; } _inPostChanged = true; try { // Do not do a foreach loop here. It's perfectly possible, and in fact expected, that the Complete // method below can trigger a series of events which leads to a nested edit and another // ITextBuffer::Changed. That event will add to the _editVersionList queue and hence break a // foreach loop while (_editVersionList.Count > 0) { var cur = _editVersionList.Dequeue(); using (ITextUndoTransaction undoTransaction = _undoHistory.CreateTransaction(Strings.TextBufferChanged)) { TextBufferChangeUndoPrimitive undoPrimitive = new TextBufferChangeUndoPrimitive(_undoHistory, cur); undoTransaction.AddUndo(undoPrimitive); undoTransaction.Complete(); } } } finally { _editVersionList.Clear(); // Ensure we cleanup state in the face of an exception _inPostChanged = false; } }
public void Dispose() { _selectionTracker.EndTracking(); _transaction.AddUndo(new EndSelectionTrackingUndoUnit(_selectionTracker, _textBuffer)); _transaction.Complete(); _transaction.Dispose(); }
public SelectionUndo(ISelectionTracker selectionTracker, ITextBufferUndoManagerProvider undoManagerProvider, string transactionName, bool automaticTracking) { _selectionTracker = selectionTracker; var undoManager = undoManagerProvider.GetTextBufferUndoManager(selectionTracker.TextView.TextBuffer); ITextUndoTransaction innerTransaction = undoManager.TextBufferUndoHistory.CreateTransaction(transactionName); _transaction = new TextUndoTransactionThatRollsBackProperly(innerTransaction); _transaction.AddUndo(new StartSelectionTrackingUndoUnit(selectionTracker)); _selectionTracker.StartTracking(automaticTracking); }
public void Dispose() { if (!EditorShell.Current.IsUnitTestEnvironment) { _selectionTracker.EndTracking(); _transaction.AddUndo(new EndSelectionTrackingUndoUnit(_selectionTracker)); _transaction.Complete(); _transaction.Dispose(); } }
public MassiveChange(ITextView textView, ITextBuffer textBuffer, ICompositionCatalog catalog, string description) { _textBuffer = textBuffer; var undoManagerProvider = catalog.ExportProvider.GetExportedValue<ITextBufferUndoManagerProvider>(); var undoManager = undoManagerProvider.GetTextBufferUndoManager(textView.TextBuffer); ITextUndoTransaction innerTransaction = undoManager.TextBufferUndoHistory.CreateTransaction(description); _transaction = new TextUndoTransactionThatRollsBackProperly(innerTransaction); _transaction.AddUndo(new StartMassiveChangeUndoUnit(_textBuffer)); IREditorDocument document = REditorDocument.TryFromTextBuffer(_textBuffer); document?.BeginMassiveChange(); }
public SelectionUndo(ISelectionTracker selectionTracker, string transactionName, bool automaticTracking) { if (!EditorShell.Current.IsUnitTestEnvironment) { _selectionTracker = selectionTracker; var undoManagerProvider = EditorShell.Current.ExportProvider.GetExport <ITextBufferUndoManagerProvider>().Value; var undoManager = undoManagerProvider.GetTextBufferUndoManager(selectionTracker.TextView.TextBuffer); ITextUndoTransaction innerTransaction = undoManager.TextBufferUndoHistory.CreateTransaction(transactionName); _transaction = new TextUndoTransactionThatRollsBackProperly(innerTransaction); _transaction.AddUndo(new StartSelectionTrackingUndoUnit(selectionTracker)); _selectionTracker.StartTracking(automaticTracking); } }
public MassiveChange(ITextView textView, ITextBuffer textBuffer, ICoreShell shell, string description) { _textBuffer = textBuffer; var undoManagerProvider = shell.GetService <ITextBufferUndoManagerProvider>(); var undoManager = undoManagerProvider.GetTextBufferUndoManager(textView.TextBuffer); ITextUndoTransaction innerTransaction = undoManager.TextBufferUndoHistory.CreateTransaction(description); _transaction = new TextUndoTransactionThatRollsBackProperly(innerTransaction); _transaction.AddUndo(new StartMassiveChangeUndoUnit(_textBuffer)); IREditorDocument document = REditorDocument.TryFromTextBuffer(_textBuffer); document?.BeginMassiveChange(); }
public MassiveChange(ITextView textView, ITextBuffer textBuffer, IServiceContainer services, string description) { _textBuffer = textBuffer; var undoManagerProvider = services.GetService <ITextBufferUndoManagerProvider>(); var undoManager = undoManagerProvider.GetTextBufferUndoManager(textView.TextBuffer); var innerTransaction = undoManager.TextBufferUndoHistory.CreateTransaction(description); _transaction = new TextUndoTransactionThatRollsBackProperly(innerTransaction); _transaction.AddUndo(new StartMassiveChangeUndoUnit(_textBuffer)); var document = _textBuffer.GetEditorDocument <IREditorDocument>(); document?.BeginMassiveChange(); }
public MassiveChange(ITextView textView, ITextBuffer textBuffer, string description) { _textBuffer = textBuffer; var undoManagerProvider = EditorShell.Current.ExportProvider.GetExport<ITextBufferUndoManagerProvider>().Value; var undoManager = undoManagerProvider.GetTextBufferUndoManager(textView.TextBuffer); ITextUndoTransaction innerTransaction = undoManager.TextBufferUndoHistory.CreateTransaction(description); _transaction = new TextUndoTransactionThatRollsBackProperly(innerTransaction); _transaction.AddUndo(new StartMassiveChangeUndoUnit(_textBuffer)); IREditorDocument document = REditorDocument.TryFromTextBuffer(_textBuffer); if(document != null) { document.BeginMassiveChange(); } }
public MassiveChange(ITextView textView, ITextBuffer textBuffer, string description) { _textBuffer = textBuffer; var undoManagerProvider = EditorShell.Current.ExportProvider.GetExport <ITextBufferUndoManagerProvider>().Value; var undoManager = undoManagerProvider.GetTextBufferUndoManager(textView.TextBuffer); ITextUndoTransaction innerTransaction = undoManager.TextBufferUndoHistory.CreateTransaction(description); _transaction = new TextUndoTransactionThatRollsBackProperly(innerTransaction); _transaction.AddUndo(new StartMassiveChangeUndoUnit(_textBuffer)); IREditorDocument document = REditorDocument.TryFromTextBuffer(_textBuffer); if (document != null) { document.BeginMassiveChange(); } }
public void Dispose() { IREditorDocument document = REditorDocument.TryFromTextBuffer(_textBuffer); bool changed = true; if (document != null) { changed = document.EndMassiveChange(); } if (!changed) { _transaction.Cancel(); } else { _transaction.AddUndo(new EndMassiveChangeUndoUnit(_textBuffer)); _transaction.Complete(); } _transaction.Dispose(); }
public void Dispose() { var document = _textBuffer.GetEditorDocument <IREditorDocument>(); var changed = true; if (document != null) { changed = document.EndMassiveChange(); } if (!changed) { _transaction.Cancel(); } else { _transaction.AddUndo(new EndMassiveChangeUndoUnit(_textBuffer)); _transaction.Complete(); } _transaction.Dispose(); }