예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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()));
        }