private async Task <bool> MakePrettierAsync() { string input = _view.TextBuffer.CurrentSnapshot.GetText(); string output = await _node.ExecuteProcessAsync(input, _encoding, _filePath); VirtualSnapshotPoint snapshotPoint = _view.Selection.ActivePoint; if (string.IsNullOrEmpty(output) || input == output) { return(false); } using (ITextEdit edit = _view.TextBuffer.CreateEdit()) using (ITextUndoTransaction undo = _undoManager.TextBufferUndoHistory.CreateTransaction("Make Prettier")) { edit.Replace(0, _view.TextBuffer.CurrentSnapshot.Length, output); edit.Apply(); undo.Complete(); } var newSnapshotPoint = new SnapshotPoint(_view.TextBuffer.CurrentSnapshot, snapshotPoint.Position.Position); _view.Caret.MoveTo(newSnapshotPoint); _view.ViewScroller.EnsureSpanVisible(new SnapshotSpan(newSnapshotPoint, 0)); return(true); }
private bool InvokeZenCoding() { ThreadHelper.ThrowIfNotOnUIThread(); Span zenSpan = GetSyntaxSpan(out string syntax); if (zenSpan.IsEmpty || _view.Selection.SelectedSpans[0].Length > 0 || !IsValidTextBuffer()) { return(false); } var parser = new Parser(); string result = parser.Parse(syntax, ZenType.HTML); if (!string.IsNullOrEmpty(result)) { using (ITextUndoTransaction undo = _undoManager.TextBufferUndoHistory.CreateTransaction("ZenCoding")) { ITextSelection selection = UpdateTextBuffer(zenSpan, result); var newSpan = new Span(zenSpan.Start, selection.SelectedSpans[0].Length); _dte.ExecuteCommand("Edit.FormatSelection"); SetCaret(newSpan, false); selection.Clear(); undo.Complete(); } return(true); } return(false); }
private void DeleteSpan(NormalizedSnapshotSpanCollection applicabilitySpans) { using (ITextUndoTransaction undoTransaction = _undoHistory.CreateTransaction("HTML Cut")) { _editorOperations.AddBeforeTextBufferChangePrimitive(); bool successfulEdit = true; using (ITextEdit edit = _textView.TextBuffer.CreateEdit()) { foreach (SnapshotSpan span in applicabilitySpans) { successfulEdit &= edit.Delete(span); } if (successfulEdit) { edit.Apply(); } } _editorOperations.AddAfterTextBufferChangePrimitive(); if (successfulEdit) { undoTransaction.Complete(); } } }
public UndoTransactionImpl(ITextUndoHistory history, ITextUndoTransaction parent, string description) { if (history == null) { throw new ArgumentNullException(nameof(history)); } if (string.IsNullOrEmpty(description)) { throw new ArgumentNullException(nameof(description)); } this.history = history as UndoHistoryImpl; if (this.history == null) { throw new ArgumentException("Strings.InvalidHistoryInTransaction"); } this.parent = parent as UndoTransactionImpl; if (this.parent == null && parent != null) { throw new ArgumentException("Strings.InvalidParentInTransaction"); } this.description = description; this.state = UndoTransactionState.Open; this.primitives = new List <ITextUndoPrimitive>(); this.mergePolicy = NullMergeUndoTransactionPolicy.Instance; this.IsReadOnly = true; }
public void OnCharTyped(char @char) { // format on ':' if (@char == RobotsTxtSyntaxFacts.NameValueDelimiter) { ITextBuffer buffer = _textView.TextBuffer; SyntaxTree syntaxTree = buffer.GetSyntaxTree(); RobotsTxtDocumentSyntax root = syntaxTree.Root as RobotsTxtDocumentSyntax; // find in syntax tree var caret = _textView.Caret.Position.BufferPosition; RobotsTxtLineSyntax lineSyntax = root.Records .SelectMany(r => r.Lines) .FirstOrDefault(p => p.DelimiterToken.Span.Span.End == caret); if (lineSyntax != null) { using (ITextUndoTransaction transaction = _undoHistory.CreateTransaction("Automatic Formatting")) { using (ITextEdit edit = buffer.CreateEdit()) { // fix indent // find property before RobotsTxtLineSyntax before = lineSyntax.Record.Lines .TakeWhile(p => p != lineSyntax) .LastOrDefault(); // reference point if (before != null) { SnapshotPoint referencePoint = before.NameToken.Span.Span.Start; // compare ITextSnapshotLine referenceLine = referencePoint.GetContainingLine(); ITextSnapshotLine line = lineSyntax.DelimiterToken.Span.Span.End.GetContainingLine(); SnapshotSpan referenceIndent = new SnapshotSpan(referenceLine.Start, referencePoint); SnapshotSpan indent = new SnapshotSpan(line.Start, lineSyntax.NameToken.Span.Span.Start); if (indent.GetText() != referenceIndent.GetText()) { edit.Replace(indent, referenceIndent.GetText()); } } // remove white space before ':' if (lineSyntax.NameToken.Span.Span.End != lineSyntax.DelimiterToken.Span.Span.Start) { edit.Delete(new SnapshotSpan(lineSyntax.NameToken.Span.Span.End, lineSyntax.DelimiterToken.Span.Span.Start)); } edit.Apply(); } transaction.Complete(); } } } }
public bool ValidTransactionForMarkers(ITextUndoTransaction transaction) { return(transaction == null || //// you can put a marker on the null transaction _currentTransaction == transaction || //// you can put a marker on the currently active transaction (transaction.History == this && transaction.State != UndoTransactionState.Invalid)); //// and you can put a marker on any transaction in this history. }
public UndoTransactionImpl(ITextUndoHistory history, ITextUndoTransaction parent, string description) { if (history == null) { throw new ArgumentNullException(nameof(history)); } if (string.IsNullOrEmpty(description)) { throw new ArgumentNullException(nameof(description)); } _history = history as UndoHistoryImpl; if (_history == null) { throw new ArgumentException("Invalid history in registry"); } _parent = parent as UndoTransactionImpl; if (_parent == null && parent != null) { throw new ArgumentException("Invalid parent in transaction"); } Description = description; _state = UndoTransactionState.Open; _primitives = new List<ITextUndoPrimitive>(); _mergePolicy = NullMergeUndoTransactionPolicy.Instance; IsReadOnly = true; }
public UndoTransactionImpl(ITextUndoHistory history, ITextUndoTransaction parent, string description) { if (history == null) { throw new ArgumentNullException(nameof(history)); } if (string.IsNullOrEmpty(description)) { throw new ArgumentNullException(nameof(description)); } _history = history as UndoHistoryImpl; if (_history == null) { throw new ArgumentException("Invalid history in registry"); } _parent = parent as UndoTransactionImpl; if (_parent == null && parent != null) { throw new ArgumentException("Invalid parent in transaction"); } Description = description; _state = UndoTransactionState.Open; _primitives = new List <ITextUndoPrimitive>(); _mergePolicy = NullMergeUndoTransactionPolicy.Instance; IsReadOnly = true; }
public bool CanMerge(ITextUndoTransaction newTransaction, ITextUndoTransaction oldTransaction) { // Validate if (newTransaction == null) { throw new ArgumentNullException(nameof(newTransaction)); } if (oldTransaction == null) { throw new ArgumentNullException(nameof(oldTransaction)); } TextTransactionMergePolicy oldPolicy = oldTransaction.MergePolicy as TextTransactionMergePolicy; TextTransactionMergePolicy newPolicy = newTransaction.MergePolicy as TextTransactionMergePolicy; if (oldPolicy == null || newPolicy == null) { throw new InvalidOperationException("The MergePolicy for both transactions should be a TextTransactionMergePolicy."); } // Make sure the merge policy directions permit merging these two transactions. if ((oldPolicy._allowableMergeDirections & TextTransactionMergeDirections.Forward) == 0 || (newPolicy._allowableMergeDirections & TextTransactionMergeDirections.Backward) == 0) { return false; } // Only merge text transactions that have the same description if (newTransaction.Description != oldTransaction.Description) { return false; } return true; }
private void OnTransactionStackCompleted(BasicUndoTransaction transaction) { Debug.Assert(_openTransactionStack.Count == 0); ITextUndoTransaction eventArgument = transaction; var result = TextUndoTransactionCompletionResult.TransactionAdded; if (_undoStack.Count > 0) { var previous = _undoStack.Peek(); if (transaction.MergePolicy != null && previous.MergePolicy != null && previous.MergePolicy.TestCompatiblePolicy(transaction.MergePolicy) && previous.MergePolicy.CanMerge(newerTransaction: transaction, olderTransaction: previous)) { eventArgument = previous; previous.MergePolicy.PerformTransactionMerge(existingTransaction: previous, newTransaction: transaction); } else { _undoStack.Push(transaction); } } else { _undoStack.Push(transaction); } var list = _undoTransactionCompleted; if (list != null) { list(this, new TextUndoTransactionCompletedEventArgs(eventArgument, result)); } }
public DragDropPointerEffects HandleDataDropped(DragDropInfo dragDropInfo) { try { SnapshotPoint position = dragDropInfo.VirtualBufferPosition.Position; string header = string.Format(_template, _ext); ITextSnapshotLine line = _view.TextBuffer.CurrentSnapshot.GetLineFromPosition(position); if (!line.Extent.IsEmpty) { header = Environment.NewLine + header; } using (ITextUndoTransaction transaction = _undoManager.TextBufferUndoHistory.CreateTransaction($"Dragged {_ext}")) using (ITextEdit edit = _view.TextBuffer.CreateEdit()) { edit.Insert(position, header); edit.Apply(); transaction.Complete(); } Telemetry.TrackUserTask("FileDragged"); } catch (Exception ex) { Telemetry.TrackException("DragDrop", ex); } return(DragDropPointerEffects.Copy); }
public TextUndoTransaction(TextUndoHistory textUndoHistory, ITextUndoTransaction parent) { _textUndoHistory = textUndoHistory; _state = UndoTransactionState.Open; _parent = parent; MergePolicy = new Policy(); }
public bool CanMerge(ITextUndoTransaction newTransaction, ITextUndoTransaction oldTransaction) { MergeUndoActionPolicy oldPolicy = oldTransaction.MergePolicy as MergeUndoActionPolicy; MergeUndoActionPolicy newPolicy = newTransaction.MergePolicy as MergeUndoActionPolicy; if (oldPolicy != null && oldPolicy._mergeNext && newPolicy != null && newPolicy._mergePrevious && oldPolicy._actionName == newPolicy._actionName) { // If one of the transactions is empty, than it is safe to merge if (newTransaction.UndoPrimitives.Count == 0 || oldTransaction.UndoPrimitives.Count == 0) { return(true); } // Make sure that we only merge consecutive edits ITextUndoPrimitive newPrimitive = newTransaction.UndoPrimitives[0]; ITextUndoPrimitive oldPrimitive = oldTransaction.UndoPrimitives[oldTransaction.UndoPrimitives.Count - 1]; return(newPrimitive.CanMerge(oldPrimitive)); } return(false); }
public UndoTransactionImpl(ITextUndoHistory history, ITextUndoTransaction parent, string description) { if (history == null) { throw new ArgumentNullException("history", String.Format(CultureInfo.CurrentUICulture, "Strings.ArgumentCannotBeNull", "UndoTransactionImpl", "history")); } if (String.IsNullOrEmpty(description)) { throw new ArgumentNullException("description", String.Format(CultureInfo.CurrentUICulture, "Strings.ArgumentCannotBeNull", "UndoTransactionImpl", "description")); } this.history = history as UndoHistoryImpl; if (this.history == null) { throw new ArgumentException("Strings.InvalidHistoryInTransaction"); } this.parent = parent as UndoTransactionImpl; if (this.parent == null && parent != null) { throw new ArgumentException("Strings.InvalidParentInTransaction"); } this.description = description; this.state = UndoTransactionState.Open; this.primitives = new List <ITextUndoPrimitive>(); this.mergePolicy = NullMergeUndoTransactionPolicy.Instance; this.IsReadOnly = true; }
/// <summary> /// Performs requested amount of redo operation and places the transactions on the undo stack. /// UNDONE: What if there is a currently opened transaction? /// </summary> /// <param name="count">The number of redo operations to perform. At the end of the operation, requested number of visible /// transactions are redone. Hence actual number of transactions redone might be more than this number if there are some /// hidden transactions adjacent to (on top of or at the bottom of) the visible ones. /// </param> /// <remarks> /// After the last visible transaction is redone, hidden transactions left on top the stack are redone as well until a /// visible or linked transaction is encountered or stack is emptied totally. /// </remarks> public void Redo(int count) { if (count <= 0) { throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, "Strings.RedoAndUndoAcceptOnlyPositiveCounts", "Redo", count), "count"); } if (!IsThereEnoughVisibleTransactions(this.redoStack, count)) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Strings.CannotUndoMoreTransactionsThanExist", "redo", count)); } TextUndoHistoryState originalState = this.state; this.state = TextUndoHistoryState.Redoing; using (new AutoEnclose(delegate { this.state = originalState; })) { while (count > 0) { if (!this.redoStack.Peek().CanRedo) { throw new InvalidOperationException("Strings.CannotRedoRequestedPrimitiveFromHistoryRedo"); } ITextUndoTransaction ut = this.redoStack.Pop(); ut.Do(); this.undoStack.Push(ut); RaiseUndoRedoHappened(this.state, ut); --count; } } }
/// <summary> /// Performs requested amount of redo operation and places the transactions on the undo stack. /// UNDONE: What if there is a currently opened transaction? /// </summary> /// <param name="count">The number of redo operations to perform. At the end of the operation, requested number of visible /// transactions are redone. Hence actual number of transactions redone might be more than this number if there are some /// hidden transactions adjacent to (on top of or at the bottom of) the visible ones. /// </param> /// <remarks> /// After the last visible transaction is redone, hidden transactions left on top the stack are redone as well until a /// visible or linked transaction is encountered or stack is emptied totally. /// </remarks> public void Redo(int count) { if (count <= 0) { throw new ArgumentOutOfRangeException(nameof(count)); } if (!IsThereEnoughVisibleTransactions(this.redoStack, count)) { throw new InvalidOperationException("Cannot redo more transactions than exist"); } TextUndoHistoryState originalState = this.state; this.state = TextUndoHistoryState.Redoing; using (new AutoEnclose(delegate { this.state = originalState; })) { while (count > 0) { if (!this.redoStack.Peek().CanRedo) { throw new InvalidOperationException("Strings.CannotRedoRequestedPrimitiveFromHistoryRedo"); } ITextUndoTransaction ut = this.redoStack.Pop(); ut.Do(); this.undoStack.Push(ut); RaiseUndoRedoHappened(this.state, ut); --count; } } }
/// <summary> /// Performs requested amount of redo operation and places the transactions on the undo stack. /// UNDONE: What if there is a currently opened transaction? /// </summary> /// <param name="count">The number of redo operations to perform. At the end of the operation, requested number of visible /// transactions are redone. Hence actual number of transactions redone might be more than this number if there are some /// hidden transactions adjacent to (on top of or at the bottom of) the visible ones. /// </param> /// <remarks> /// After the last visible transaction is redone, hidden transactions left on top the stack are redone as well until a /// visible or linked transaction is encountered or stack is emptied totally. /// </remarks> public void Redo(int count) { if (count <= 0) { throw new ArgumentException("count must be > 0", nameof(count)); } if (!IsThereEnoughVisibleTransactions(_redoStack, count)) { throw new InvalidOperationException("No more undos/redos on the stack"); } TextUndoHistoryState originalState = _state; _state = TextUndoHistoryState.Redoing; using (new AutoEnclose(delegate { this._state = originalState; })) { while (count > 0) { if (!_redoStack.Peek().CanRedo) { throw new InvalidOperationException("Cannot redo/ask primitive from stack"); } ITextUndoTransaction ut = _redoStack.Pop(); ut.Do(); _undoStack.Push(ut); RaiseUndoRedoHappened(_state, ut); --count; } } }
/// <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 PerformTransactionMerge(ITextUndoTransaction existingTransaction, ITextUndoTransaction newTransaction) { // Add all of our commit primitives into the existing transaction foreach (var primitive in newTransaction.UndoPrimitives) { existingTransaction.UndoPrimitives.Add(primitive); } }
private void RaiseUndoRedoHappened(TextUndoHistoryState state, ITextUndoTransaction transaction) { EventHandler <TextUndoRedoEventArgs> undoRedoHappened = UndoRedoHappened; if (undoRedoHappened != null) { undoRedoHappened(this, new TextUndoRedoEventArgs(state, transaction)); } }
public TextUndoTransaction(TextUndoHistory history, ITextUndoTransaction parent, string description) { this.history = history ?? throw new ArgumentNullException(nameof(history)); Parent = parent; undoPrimitives = new List <ITextUndoPrimitive>(); readOnlyUndoPrimitives = new ReadOnlyCollection <ITextUndoPrimitive>(undoPrimitives); State = UndoTransactionState.Open; this.description = description ?? throw new ArgumentNullException(nameof(description)); }
private void RaiseUndoTransactionCompleted(ITextUndoTransaction transaction, TextUndoTransactionCompletionResult result) { EventHandler <TextUndoTransactionCompletedEventArgs> undoTransactionAdded = UndoTransactionCompleted; if (undoTransactionAdded != null) { undoTransactionAdded(this, new TextUndoTransactionCompletedEventArgs(transaction, result)); } }
public void PreOverType(out bool handledCommand) { handledCommand = false; if (ClosingPoint == null) { return; } // Brace completion is not cancellable. var cancellationToken = CancellationToken.None; var snapshot = this.SubjectBuffer.CurrentSnapshot; var document = snapshot.GetOpenDocumentInCurrentContextWithChanges(); SnapshotPoint closingSnapshotPoint = ClosingPoint.GetPoint(snapshot); if (!HasForwardTyping && _session.AllowOverType(this, cancellationToken)) { SnapshotPoint?caretPos = this.GetCaretPosition(); Debug.Assert(caretPos.HasValue && caretPos.Value.Position < closingSnapshotPoint.Position); // ensure that we are within the session before clearing if (caretPos.HasValue && caretPos.Value.Position < closingSnapshotPoint.Position && closingSnapshotPoint.Position > 0) { using (ITextUndoTransaction undo = CreateUndoTransaction()) { _editorOperations.AddBeforeTextBufferChangePrimitive(); SnapshotSpan span = new SnapshotSpan(caretPos.Value, closingSnapshotPoint.Subtract(1)); using (ITextEdit edit = SubjectBuffer.CreateEdit()) { edit.Delete(span); if (edit.HasFailedChanges) { Debug.Fail("Unable to clear closing brace"); edit.Cancel(); undo.Cancel(); } else { handledCommand = true; edit.Apply(); MoveCaretToClosingPoint(); _editorOperations.AddAfterTextBufferChangePrimitive(); undo.Complete(); } } } } } }
internal bool Begin(ITextUndoHistory undoHistory) { if (undoHistory != null) { _transaction = new HACK_TextUndoTransactionThatRollsBackProperly(undoHistory.CreateTransaction(Description)); return(true); } return(false); }
private void EndTransaction() { if (_transaction != null) { _transaction.Dispose(); _transaction = null; } _active = false; }
internal bool Begin(ITextUndoHistory undoHistory) { if (undoHistory != null) { _transaction = new HACK_TextUndoTransactionThatRollsBackProperly(undoHistory.CreateTransaction(Description)); return true; } return false; }
public TextUndoTransaction(TextUndoHistory history, ITextUndoTransaction parent, string description) { if (history == null) throw new ArgumentNullException(nameof(history)); if (description == null) throw new ArgumentNullException(nameof(description)); this.history = history; Parent = parent; undoPrimitives = new List<ITextUndoPrimitive>(); readOnlyUndoPrimitives = new ReadOnlyCollection<ITextUndoPrimitive>(undoPrimitives); State = UndoTransactionState.Open; this.description = description; }
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 MockTextUndoTransaction(ITextUndoHistory history, ITextUndoTransaction parent, string description) { _history = history as MockTextUndoHistory; _parent = parent as MockTextUndoTransaction; Description = description; _state = UndoTransactionState.Open; _primitives = new List<ITextUndoPrimitive>(); MergePolicy = NullMergeUndoTransactionPolicy.Instance; IsReadOnly = true; }
public ITextUndoTransaction CreateTransaction(string description) { if (_currentTransaction != null) { return new TextUndoTransaction(this, _currentTransaction); } else { _currentTransaction = new TextUndoTransaction(this); return _currentTransaction; } }
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(); }
bool ExecuteCommandCore(EditorCommandArgs args, CommandExecutionContext context, Operation operation) { ITextView textView = args.TextView; ITextBuffer textBuffer = args.SubjectBuffer; if (!XmlBackgroundParser.TryGetParser(textBuffer, out var parser)) { return(false); } var xmlParseResult = parser.GetOrProcessAsync(textBuffer.CurrentSnapshot, default).Result; var xmlDocumentSyntax = xmlParseResult.XDocument; if (xmlDocumentSyntax == null) { return(false); } string description = operation.ToString(); var editorOperations = editorOperationsFactoryService.GetEditorOperations(textView); var multiSelectionBroker = textView.GetMultiSelectionBroker(); var selectedSpans = multiSelectionBroker.AllSelections.Select(selection => selection.Extent); using (context.OperationContext.AddScope(allowCancellation: false, description: description)) { ITextUndoHistory undoHistory = undoHistoryRegistry.RegisterHistory(textBuffer); using (ITextUndoTransaction undoTransaction = undoHistory.CreateTransaction(description)) { switch (operation) { case Operation.Comment: CommentSelection(textBuffer, selectedSpans, xmlDocumentSyntax, editorOperations, multiSelectionBroker); break; case Operation.Uncomment: UncommentSelection(textBuffer, selectedSpans, xmlDocumentSyntax); break; case Operation.Toggle: ToggleCommentSelection(textBuffer, selectedSpans, xmlDocumentSyntax, editorOperations, multiSelectionBroker); break; } undoTransaction.Complete(); } } return(true); }
/// <summary> /// Commits all modifications made with specified <see cref="ITextBufferEdit"/> and link the commit /// with <see cref="ITextUndoTransaction"/> in the Editor, if <see cref="_undoHistory"/> is available. /// </summary> /// <param name="edit">A set of editing operations on an <see cref="ITextBuffer"/>.</param> /// <param name="description">The description of the transaction.</param> private void ApplyEdit(ITextBufferEdit edit, string description) { if (_undoHistory != null) { using (ITextUndoTransaction transaction = _undoHistory.CreateTransaction(description)) { edit.Apply(); transaction.Complete(); } } else { edit.Apply(); } }
public void PreOverType(out bool handledCommand) { handledCommand = false; // AllowOverType may make changes to the buffer such as for completing intellisense if (!HasForwardTyping && (_context == null || _context.AllowOverType(this))) { SnapshotPoint?caretPos = CaretPosition; SnapshotPoint closingSnapshotPoint = _closingPoint.GetPoint(SubjectBuffer.CurrentSnapshot); Debug.Assert(caretPos.HasValue && caretPos.Value.Position < closingSnapshotPoint.Position); // ensure that we are within the session before clearing if (caretPos.HasValue && caretPos.Value.Position < closingSnapshotPoint.Position && closingSnapshotPoint.Position > 0) { using (ITextUndoTransaction undo = CreateUndoTransaction()) { _editorOperations.AddBeforeTextBufferChangePrimitive(); SnapshotSpan span = new SnapshotSpan(caretPos.Value, closingSnapshotPoint.Subtract(1)); using (ITextEdit edit = _subjectBuffer.CreateEdit()) { edit.Delete(span); if (edit.HasFailedChanges) { Debug.Fail("Unable to clear closing brace"); edit.Cancel(); undo.Cancel(); } else { handledCommand = true; edit.Apply(); MoveCaretToClosingPoint(); _editorOperations.AddAfterTextBufferChangePrimitive(); undo.Complete(); } } } } } }
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 void Open(string name) { Debug.Assert(_undoTransaction == null); if (_undoTransaction == null && _undoManager != null && _editorOperations != null) { _undoTransaction = _undoManager.TextBufferUndoHistory.CreateTransaction(name); if (_addRollbackOnCancel) { // Some hosts (*cough* VS *cough*) don't properly implement ITextUndoTransaction such // that their Cancel operation doesn't rollback the already performed actions. // In those scenarios, we'll use our own rollback mechanism (unabashedly copied // from Roslyn) _undoTransaction = new TextUndoTransactionThatRollsBackProperly(_undoTransaction); } _editorOperations.AddBeforeTextBufferChangePrimitive(); } }
public CaretPreservingEditTransaction( string description, ITextView textView, ITextUndoHistoryRegistry undoHistoryRegistry, IEditorOperationsFactoryService editorOperationsFactoryService) { _editorOperations = editorOperationsFactoryService.GetEditorOperations(textView); _undoHistory = undoHistoryRegistry.GetHistory(textView.TextBuffer); _active = true; if (_undoHistory != null) { _transaction = new HACK_TextUndoTransactionThatRollsBackProperly(_undoHistory.CreateTransaction(description)); _editorOperations.AddBeforeTextBufferChangePrimitive(); } }
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 PerformTransactionMerge(ITextUndoTransaction existingTransaction, ITextUndoTransaction newTransaction) { if (existingTransaction == null) throw new ArgumentNullException("existingTransaction"); if (newTransaction == null) throw new ArgumentNullException("newTransaction"); // Remove trailing AfterTextBufferChangeUndoPrimitive from previous transaction and skip copying // initial BeforeTextBufferChangeUndoPrimitive from newTransaction, as they are unnecessary. int copyStartIndex = 0; // Copy items from newTransaction into existingTransaction. for (int i = copyStartIndex; i < newTransaction.UndoPrimitives.Count; i++) { existingTransaction.UndoPrimitives.Add(newTransaction.UndoPrimitives[i]); } }
public void PerformTransactionMerge(ITextUndoTransaction oldTransaction, ITextUndoTransaction newTransaction) { MergeUndoActionPolicy oldPolicy = (MergeUndoActionPolicy)oldTransaction.MergePolicy; MergeUndoActionPolicy newPolicy = (MergeUndoActionPolicy)newTransaction.MergePolicy; // Remove trailing AfterTextBufferChangeUndoPrimitive from previous transaction and skip copying // initial BeforeTextBufferChangeUndoPrimitive from newTransaction, as they are unnecessary. if (oldTransaction.UndoPrimitives.Count > 0 && oldPolicy._addedTextChangePrimitives) { oldTransaction.UndoPrimitives.RemoveAt(oldTransaction.UndoPrimitives.Count - 1); } int copyStartIndex = newPolicy._addedTextChangePrimitives ? 1 : 0; for (int i = copyStartIndex; i < newTransaction.UndoPrimitives.Count; i++) { oldTransaction.UndoPrimitives.Add(newTransaction.UndoPrimitives[i]); } }
private void FormatDocument() { using (ITextUndoTransaction transaction = _undoManager.TextBufferUndoHistory.CreateTransaction(Resources.Text.FormatDocument)) { EditorConfigFormatter formatter = _view.Properties.GetOrCreateSingletonProperty(() => new EditorConfigFormatter(_view.TextBuffer)); bool changed = formatter.Format(); if (changed) { transaction.Complete(); } else { transaction.Cancel(); } } }
public bool CanMerge(ITextUndoTransaction newTransaction, ITextUndoTransaction oldTransaction) { MergeUndoActionPolicy oldPolicy = oldTransaction.MergePolicy as MergeUndoActionPolicy; MergeUndoActionPolicy newPolicy = newTransaction.MergePolicy as MergeUndoActionPolicy; if (oldPolicy != null && oldPolicy._mergeNext && newPolicy != null && newPolicy._mergePrevious && oldPolicy._actionName == newPolicy._actionName) { // If one of the transactions is empty, than it is safe to merge if (newTransaction.UndoPrimitives.Count == 0 || oldTransaction.UndoPrimitives.Count == 0) { return true; } // Make sure that we only merge consecutive edits ITextUndoPrimitive newPrimitive = newTransaction.UndoPrimitives[0]; ITextUndoPrimitive oldPrimitive = oldTransaction.UndoPrimitives[oldTransaction.UndoPrimitives.Count - 1]; return newPrimitive.CanMerge(oldPrimitive); } return false; }
public HACK_TextUndoTransactionThatRollsBackProperly(ITextUndoTransaction innerTransaction) { _innerTransaction = innerTransaction; _undoPrimitive = new RollbackDetectingUndoPrimitive(); }
private void RaiseUndoRedoHappened(TextUndoHistoryState state, ITextUndoTransaction transaction) { EventHandler<TextUndoRedoEventArgs> undoRedoHappened = UndoRedoHappened; undoRedoHappened?.Invoke(this, new TextUndoRedoEventArgs(state, transaction)); }
private void RaiseUndoTransactionCompleted(ITextUndoTransaction transaction, TextUndoTransactionCompletionResult result) { EventHandler<TextUndoTransactionCompletedEventArgs> undoTransactionAdded = UndoTransactionCompleted; undoTransactionAdded?.Invoke(this, new TextUndoTransactionCompletedEventArgs(transaction, result)); }
public void PerformTransactionMerge(ITextUndoTransaction existingTransaction, ITextUndoTransaction newTransaction) { throw new InvalidOperationException("Strings.NullMergePolicyCannotMerge"); }
public bool CanMerge(ITextUndoTransaction newerTransaction, ITextUndoTransaction olderTransaction) { return false; }
public bool CanMerge(ITextUndoTransaction newerTransaction, ITextUndoTransaction olderTransaction) { // We want to merge with any other transaction of our policy type return true; }
public void PerformTransactionMerge(ITextUndoTransaction existingTransaction, ITextUndoTransaction newTransaction) { throw new NotImplementedException(); }
public bool ValidTransactionForMarkers(ITextUndoTransaction transaction) { return transaction == null //// you can put a marker on the null transaction || _currentTransaction == transaction //// you can put a marker on the currently active transaction || (transaction.History == this && transaction.State != UndoTransactionState.Invalid); //// and you can put a marker on any transaction in this history. }
public ITextUndoTransaction CreateTransaction(string description) { _currentTransaction = new TextUndoTransaction(this); return _currentTransaction; }
/// <summary> /// This is how the transactions alert their containing history that they have finished /// (likely from the Dispose() method). /// </summary> /// <param name="transaction">This is the transaction that's finishing. It should match the history's current transaction. /// If it does not match, then the current transaction will be discarded and an exception will be thrown.</param> public void EndTransaction(ITextUndoTransaction transaction) { if (_currentTransaction != transaction) { _currentTransaction = null; throw new InvalidOperationException("Strings.EndTransactionOutOfOrder"); } // only add completed transactions to their parents (or the stack) if (_currentTransaction.State == UndoTransactionState.Completed) { if (_currentTransaction.Parent == null) // stack bottomed out! { MergeOrPushToUndoStack(_currentTransaction); } } _currentTransaction = _currentTransaction.Parent as UndoTransactionImpl; }
public InteractiveGlobalUndoTransaction(ITextUndoTransaction transaction) { _transaction = transaction; }