/// <summary> /// Executes the emacs command /// </summary> /// <param name="view"></param> /// <param name="metadata"></param> public void Execute(ITextView view, IEmacsCommandMetadata metadata, bool evaluateUniversalArgument = true) { using (BufferMonitor bufferMonitor = BufferMonitor.Create(view.TextBuffer)) { try { EmacsCommand command = CreateCommand(metadata); EmacsCommand inverseCommand = null; IEmacsCommandMetadata inverseCommandMetadata = null; var context = new EmacsCommandContext( this, this.TextStructureNavigatorSelectorService, this.EditorOperationsFactoryService.GetEditorOperations(view), view, CommandRouterProvider.GetCommandRouter(view)); if (command != null) { var history = this.TextUndoHistoryRegistry.GetHistory(context.TextBuffer); using (var transaction = CreateTransaction(metadata, history)) { var repeatCount = 1; bool shouldExecuteInverse = false; if (evaluateUniversalArgument) { // Check if we should execute the inverse logic of the command by checking if the universal argument is lower than 0 shouldExecuteInverse = GetUniversalArgumentOrDefault() < 0; if (shouldExecuteInverse) { // Search the inverse command using the metadata inverseCommandMetadata = GetCommandMetadata(metadata.InverseCommand); inverseCommand = CreateCommand(inverseCommandMetadata); } // If the command specifies that can be repeated use the universal argument as the counter, otherwise execute the command only once. if (metadata.CanBeRepeated) { repeatCount = Math.Abs(GetUniversalArgumentOrDefault(1)); } } for (; repeatCount > 0; repeatCount--) { if (shouldExecuteInverse) { // Execute the inverse logic if (inverseCommand != null) { inverseCommand.Execute(context); } else { command.ExecuteInverse(context); } } else { // Execute the normal logic command.Execute(context); } } // TODO: Check command error and rollback the transaction if (transaction != null) { transaction.Complete(); } // If the command executed was a kill command, then we want to append the text that was cut // to any currently text cut for the view. // If the command is not a kill command and we have had some cut commands executed previously // that accumulated deleted text, then we want to put the data on the clipboard and reset // the accumulated text. if (metadata.IsKillCommand) { view.AppendKillString(bufferMonitor.BufferChanges); } else { view.FlushKillSring(this.ClipboardRing); } this.LastExecutedCommand = shouldExecuteInverse ? inverseCommandMetadata : metadata; } } } catch (NoOperationException) { // Do nothing } } }
public void Execute(ITextView view, IEmacsCommandMetadata metadata, bool evaluateUniversalArgument = true) { try { changes = new StringBuilder(); view.TextBuffer.Changed += OnTextBufferChanged; EmacsCommand command = CreateCommand(metadata); EmacsCommand emacsCommand = null; IEmacsCommandMetadata metadata1 = null; var context = new EmacsCommandContext(this, TextStructureNavigatorSelectorService, EditorOperationsFactoryService.GetEditorOperations(view), view, CommandRouterProvider.GetCommandRouter(view)); if (ClipboardRing.Count == 0 || ClipboardRing.Last() != Clipboard.GetText()) { ClipboardRing.Add(Clipboard.GetText()); } if (command == null) { return; } ITextUndoHistory history = TextUndoHistoryRegistry.GetHistory(context.TextBuffer); using (ITextUndoTransaction transaction = CreateTransaction(metadata, history)) { int num = 1; bool flag = false; if (evaluateUniversalArgument) { flag = GetUniversalArgumentOrDefault(0) < 0; if (flag) { metadata1 = GetCommandMetadata(metadata.InverseCommand); emacsCommand = CreateCommand(metadata1); } if (metadata.CanBeRepeated) { num = Math.Abs(GetUniversalArgumentOrDefault(1)); } } for (; num > 0; --num) { if (flag) { if (emacsCommand != null) { emacsCommand.Execute(context); } else { command.ExecuteInverse(context); } } else { command.Execute(context); } } if (transaction != null) { transaction.Complete(); } if (context.Clipboard.Length > 0) { ClipboardRing.Add(context.Clipboard.ToString()); Clipboard.SetText(context.Clipboard.ToString()); } else if (changes.Length > 0 && metadata.CopyDeletedTextToTheClipboard) { ClipboardRing.Add(changes.ToString()); Clipboard.SetText(changes.ToString()); } LastExecutedCommand = flag ? metadata1 : metadata; } } catch (NoOperationException ex) { } finally { view.TextBuffer.Changed -= OnTextBufferChanged; } }