/// <summary> /// Try and convert the Visual Studio command to it's equivalent KeyInput /// </summary> internal bool TryConvert(Guid commandGroup, uint commandId, IntPtr variantIn, out EditCommand editCommand) { editCommand = null; // Don't ever process a command when we are in an automation function. Doing so will cause VsVim to // intercept items like running Macros and certain wizard functionality if (_vsAdapter.InAutomationFunction) { return(false); } // Don't intercept commands while incremental search is active. Don't want to interfere with it if (_vsAdapter.IsIncrementalSearchActive(_vimBuffer.TextView)) { return(false); } var modifiers = _keyUtil.GetKeyModifiers(_vsAdapter.KeyboardDevice.Modifiers); if (!OleCommandUtil.TryConvert(commandGroup, commandId, variantIn, modifiers, out editCommand)) { return(false); } // Don't process Visual Studio commands. If the key sequence is mapped to a Visual Studio command // then that command wins. if (editCommand.EditCommandKind == EditCommandKind.VisualStudioCommand) { return(false); } return(true); }
internal bool IsEditCommand(Guid commandGroup, uint commandId) { EditCommand command; return(OleCommandUtil.TryConvert(commandGroup, commandId, out command) && command.HasKeyInput); }
internal bool IsEditCommand(Guid commandGroup, uint commandId) { EditCommand command; return (OleCommandUtil.TryConvert(commandGroup, commandId, IntPtr.Zero, KeyModifiers.None, out command) && command.HasKeyInput); }
/// <summary> /// Try and exec this KeyInput in an intercepted fashion /// </summary> private bool TryExecIntercepted(ref Guid commandGroup, ref OleCommandData oleCommandData, KeyInput originalKeyInput, KeyInput mappedKeyInput) { bool intercepted; bool result; Guid mappedCommandGroup; OleCommandData mappedOleCommandData; if (originalKeyInput == mappedKeyInput) { // No changes so just use the original OleCommandData result = VSConstants.S_OK == _nextTarget.Exec( ref commandGroup, oleCommandData.CommandId, oleCommandData.CommandExecOpt, oleCommandData.VariantIn, oleCommandData.VariantOut); intercepted = true; } else if (OleCommandUtil.TryConvert(mappedKeyInput, out mappedCommandGroup, out mappedOleCommandData)) { result = VSConstants.S_OK == _nextTarget.Exec( ref mappedCommandGroup, mappedOleCommandData.CommandId, mappedOleCommandData.CommandExecOpt, mappedOleCommandData.VariantIn, mappedOleCommandData.VariantOut); intercepted = true; OleCommandData.Release(ref mappedOleCommandData); } else { // If we couldn't process it using intercepting mechanism then just go straight to the IVimBuffer // for processing. result = _buffer.Process(originalKeyInput); intercepted = false; } if (intercepted) { // We processed the input and bypassed the IVimBuffer instance. We need to tell IVimBuffer this // KeyInput was processed so it can track it for macro purposes. Make sure to track the mapped // KeyInput value. The SimulateProcessed method does not mapping _buffer.SimulateProcessed(mappedKeyInput); } return(result); }
/// <summary> /// Try and process the given KeyInput for insert mode in the middle of an Exec. This is /// called for commands which can't be processed directly like edits. We'd prefer these /// go through Visual Studio's command system so items like Intellisense work properly. /// </summary> private bool TryProcessWithExec(Guid commandGroup, OleCommandData oleCommandData, IInsertMode insertMode, KeyInput originalKeyInput, KeyInput mappedKeyInput) { Func <bool> customProcess = () => { var versionNumber = _textBuffer.CurrentSnapshot.Version.VersionNumber; int? hr = null; Guid mappedCommandGroup; OleCommandData mappedOleCommandData; if (originalKeyInput == mappedKeyInput) { // No changes so just use the original OleCommandData hr = _nextTarget.Exec( ref commandGroup, oleCommandData.CommandId, oleCommandData.CommandExecOpt, oleCommandData.VariantIn, oleCommandData.VariantOut); } else if (OleCommandUtil.TryConvert(mappedKeyInput, out mappedCommandGroup, out mappedOleCommandData)) { hr = _nextTarget.Exec( ref mappedCommandGroup, mappedOleCommandData.CommandId, mappedOleCommandData.CommandExecOpt, mappedOleCommandData.VariantIn, mappedOleCommandData.VariantOut); OleCommandData.Release(ref mappedOleCommandData); } if (hr.HasValue) { // Whether or not an Exec succeeded is a bit of a heuristic. IOleCommandTarget implementations like // C++ will return E_ABORT if Intellisense failed but the character was actually inserted into // the ITextBuffer. VsVim really only cares about the character insert. However we must also // consider cases where the character successfully resulted in no action as a success return(ErrorHandler.Succeeded(hr.Value) || versionNumber < _textBuffer.CurrentSnapshot.Version.VersionNumber); } // Couldn't map to a Visual Studio command so it didn't succeed return(false); }; return(insertMode.CustomProcess(mappedKeyInput, customProcess.ToFSharpFunc())); }
internal static int Exec(this IOleCommandTarget oleCommandTarget, KeyInput keyInput) { var oleCommandData = OleCommandData.Empty; try { if (!OleCommandUtil.TryConvert(keyInput, out oleCommandData)) { return(VSConstants.E_FAIL); } return(oleCommandTarget.Exec(oleCommandData)); } finally { oleCommandData.Dispose(); } }
/// <summary> /// Try and convert the Visual Studio command to it's equivalent KeyInput /// </summary> internal bool TryConvert(Guid commandGroup, uint commandId, IntPtr pvaIn, out EditCommand editCommand) { editCommand = null; // Don't ever process a command when we are in an automation function. Doing so will cause VsVim to // intercept items like running Macros and certain wizard functionality if (_vsAdapter.InAutomationFunction) { return(false); } // Don't intercept commands while incremental search is active. Don't want to interfere with it if (_vsAdapter.IsIncrementalSearchActive(_buffer.TextView)) { return(false); } return(OleCommandUtil.TryConvert(commandGroup, commandId, pvaIn, out editCommand)); }