internal bool Exec(EditCommand editCommand, out Action preAction, out Action postAction) { preAction = null; postAction = null; // If the KeyInput was already handled then pretend we handled it here if (editCommand.HasKeyInput && _vimBufferCoordinator.IsDiscarded(editCommand.KeyInput)) { return(true); } switch (editCommand.EditCommandKind) { case EditCommandKind.Undo: // The user hit the undo button. Don't attempt to map anything here and instead just // run a single Vim undo operation _vimBuffer.UndoRedoOperations.Undo(1); return(true); case EditCommandKind.Redo: // The user hit the redo button. Don't attempt to map anything here and instead just // run a single Vim redo operation _vimBuffer.UndoRedoOperations.Redo(1); return(true); case EditCommandKind.Paste: return(Paste()); case EditCommandKind.GoToDefinition: // The GoToDefinition command will often cause a selection to occur in the // buffer. We don't want that to cause us to enter Visual Mode so clear it // out. This command can cause the active document to switch if the target // of the goto def is in another file. This file won't be registered as the // active file yet so just clear out the active selections List <ITextView> selected = null; preAction = () => { // Record which buffers have pre-existing selections. selected = _textManager .GetDocumentTextViews(DocumentLoad.RespectLazy) .Where(x => !x.Selection.IsEmpty) .ToList(); }; postAction = () => { // Clear any new selections. _textManager.GetDocumentTextViews(DocumentLoad.RespectLazy) .Where(x => !x.Selection.IsEmpty && !selected.Contains(x)) .ForEach(x => { // Move the caret to the beginning of the selection. var startPoint = x.Selection.Start; x.Selection.Clear(); x.Caret.MoveTo(startPoint); }); }; return(false); case EditCommandKind.Comment: case EditCommandKind.Uncomment: // The comment / uncomment command will often induce a selection on the // editor even if there was no selection before the command was run (single line // case). if (_textView.Selection.IsEmpty) { postAction = () => { _textView.Selection.Clear(); }; } return(false); case EditCommandKind.UserInput: case EditCommandKind.VisualStudioCommand: if (editCommand.HasKeyInput) { var keyInput = editCommand.KeyInput; // Discard the input if it's been flagged by a previous QueryStatus if (_vimBufferCoordinator.IsDiscarded(keyInput)) { return(true); } // Try and process the command with the IVimBuffer if (TryProcessWithBuffer(keyInput)) { return(true); } // Discard any other unprocessed printable input in // non-input modes. Without this, Visual Studio will // see the command as unhandled and will try to handle // it itself by inserting the character into the // buffer. if (editCommand.EditCommandKind == EditCommandKind.UserInput && CharUtil.IsPrintable(keyInput.Char) && (_vimBuffer.ModeKind == ModeKind.Normal || _vimBuffer.ModeKind.IsAnyVisual())) { _commonOperations.Beep(); return(true); } } return(false); default: Debug.Assert(false); return(false); } }
internal bool Exec(EditCommand editCommand, out Action preAction, out Action postAction) { preAction = null; postAction = null; // If the KeyInput was already handled then pretend we handled it // here. if (editCommand.HasKeyInput && _vimBufferCoordinator.IsDiscarded(editCommand.KeyInput)) { return(true); } switch (editCommand.EditCommandKind) { case EditCommandKind.Undo: // The user hit the undo button. Don't attempt to map // anything here and instead just run a single Vim undo // operation _vimBuffer.UndoRedoOperations.Undo(1); return(true); case EditCommandKind.Redo: // The user hit the redo button. Don't attempt to map // anything here and instead just run a single Vim redo // operation _vimBuffer.UndoRedoOperations.Redo(1); return(true); case EditCommandKind.Paste: return(Paste()); case EditCommandKind.GoToDefinition: // The GoToDefinition command will often cause a selection // to occur in the buffer. { var handler = new UnwantedSelectionHandler(_vimBuffer.Vim); preAction = handler.PreAction; postAction = handler.PostAction; } return(false); case EditCommandKind.Comment: case EditCommandKind.Uncomment: // The comment / uncomment command will often induce a // selection on the editor even if there was no selection // before the command was run (single line case). if (_textView.Selection.IsEmpty) { var handler = new UnwantedSelectionHandler(_vimBuffer.Vim); postAction = () => handler.ClearSelection(_textView); } return(false); case EditCommandKind.UserInput: case EditCommandKind.VisualStudioCommand: if (editCommand.HasKeyInput) { var keyInput = editCommand.KeyInput; // Discard the input if it's been flagged by a previous // QueryStatus. if (_vimBufferCoordinator.IsDiscarded(keyInput)) { return(true); } // Try and process the command with the IVimBuffer. if (TryProcessWithBuffer(keyInput)) { return(true); } // Discard any other unprocessed printable input in // non-input modes. Without this, Visual Studio will // see the command as unhandled and will try to handle // it itself by inserting the character into the // buffer. if (editCommand.EditCommandKind == EditCommandKind.UserInput && CharUtil.IsPrintable(keyInput.Char) && (_vimBuffer.ModeKind == ModeKind.Normal || _vimBuffer.ModeKind.IsAnyVisual())) { _commonOperations.Beep(); return(true); } } return(false); default: Debug.Assert(false); return(false); } }