示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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();
                }
            }
        }
示例#4
0
        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;
        }
示例#5
0
            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();
                        }
                    }
                }
            }
示例#6
0
 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;
        }
示例#8
0
        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;
        }
示例#10
0
        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));
            }
        }
示例#11
0
        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);
        }
示例#12
0
 public TextUndoTransaction(TextUndoHistory textUndoHistory, ITextUndoTransaction parent)
 {
     _textUndoHistory = textUndoHistory;
     _state = UndoTransactionState.Open;
     _parent = parent;
     MergePolicy = new Policy();
 }
示例#13
0
        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);
        }
示例#14
0
        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;
        }
示例#15
0
        /// <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;
                }
            }
        }
示例#16
0
        /// <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;
                }
            }
        }
示例#17
0
        /// <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);
     }
 }
 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);
     }
 }
示例#21
0
        private void RaiseUndoRedoHappened(TextUndoHistoryState state, ITextUndoTransaction transaction)
        {
            EventHandler <TextUndoRedoEventArgs> undoRedoHappened = UndoRedoHappened;

            if (undoRedoHappened != null)
            {
                undoRedoHappened(this, new TextUndoRedoEventArgs(state, transaction));
            }
        }
示例#22
0
 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));
 }
示例#23
0
        private void RaiseUndoTransactionCompleted(ITextUndoTransaction transaction, TextUndoTransactionCompletionResult result)
        {
            EventHandler <TextUndoTransactionCompletedEventArgs> undoTransactionAdded = UndoTransactionCompleted;

            if (undoTransactionAdded != null)
            {
                undoTransactionAdded(this, new TextUndoTransactionCompletedEventArgs(transaction, result));
            }
        }
示例#24
0
            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;
            }
示例#28
0
		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;
		}
示例#29
0
        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);
        }
示例#30
0
        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;
        }
示例#31
0
 public ITextUndoTransaction CreateTransaction(string description)
 {
     if (_currentTransaction != null)
     {
         return new TextUndoTransaction(this, _currentTransaction);
     }
     else
     {
         _currentTransaction = new TextUndoTransaction(this);
         return _currentTransaction;
     }
 }
示例#32
0
        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);
        }
示例#34
0
 /// <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();
     }
 }
示例#35
0
        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();
                            }
                        }
                    }
                }
            }
        }
示例#36
0
        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);
            }
        }
示例#37
0
        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 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();
            }
        }
示例#40
0
        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();
            }
        }
示例#41
0
        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]);
            }
        }
示例#43
0
        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();
 }
示例#46
0
 private void RaiseUndoRedoHappened(TextUndoHistoryState state, ITextUndoTransaction transaction) {
     EventHandler<TextUndoRedoEventArgs> undoRedoHappened = UndoRedoHappened;
     undoRedoHappened?.Invoke(this, new TextUndoRedoEventArgs(state, transaction));
 }
示例#47
0
 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;
 }
示例#51
0
 public void PerformTransactionMerge(ITextUndoTransaction existingTransaction, ITextUndoTransaction newTransaction)
 {
     throw new NotImplementedException();
 }
示例#52
0
 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.
 }
示例#53
0
 public ITextUndoTransaction CreateTransaction(string description)
 {
     _currentTransaction = new TextUndoTransaction(this);
     return _currentTransaction;
 }
        private void EndTransaction()
        {
            if (_transaction != null)
            {
                _transaction.Dispose();
                _transaction = null;
            }

            _active = false;
        }
示例#55
0
        /// <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;
 }