protected override int InternalExec()

in src/NuGet.Clients/NuGet.Console/WpfConsole/WpfConsoleKeyProcessor.cs [155:398]


        protected override int InternalExec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            int hr = OLECMDERR_E_NOTSUPPORTED;

            if (WpfConsole == null
                || WpfConsole.Host == null
                || WpfConsole.Dispatcher == null)
            {
                return hr;
            }

            if (!WpfConsole.Host.IsCommandEnabled)
            {
                return hr;
            }

            if (!WpfConsole.Dispatcher.IsExecutingReadKey)
            {
                // if the console has not been successfully started, do not accept any key inputs, unless
                // we are in the middle of a ReadKey call. This happens when the execution group policy setting
                // is set to AllSigned, and PS is asking user to trust the certificate.
                if (!WpfConsole.Dispatcher.IsStartCompleted)
                {
                    return hr;
                }

                // if the console is in the middle of executing a command, do not accept any key inputs unless
                // we are in the middle of a ReadKey call. 
                if (WpfConsole.Dispatcher.IsExecutingCommand)
                {
                    return hr;
                }
            }

            if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
            {
                //Debug.Print("Exec: GUID_VSStandardCommandSet97: {0}", (VSConstants.VSStd97CmdID)nCmdID);

                switch ((VSConstants.VSStd97CmdID)nCmdID)
                {
                    case VSConstants.VSStd97CmdID.Paste:
                        if (IsCaretInReadOnlyRegion || IsSelectionReadonly)
                        {
                            hr = VSConstants.S_OK; // eat it
                        }
                        else
                        {
                            PasteText(ref hr);
                        }
                        break;
                }
            }
            else if (pguidCmdGroup == VSConstants.VSStd2K)
            {
                //Debug.Print("Exec: VSStd2K: {0}", (VSConstants.VSStd2KCmdID)nCmdID);

                var commandID = (VSConstants.VSStd2KCmdID)nCmdID;

                if (WpfConsole.Dispatcher.IsExecutingReadKey)
                {
                    switch (commandID)
                    {
                        case VSConstants.VSStd2KCmdID.TYPECHAR:
                        case VSConstants.VSStd2KCmdID.BACKSPACE:
                        case VSConstants.VSStd2KCmdID.RETURN:
                            var keyInfo = GetVsKeyInfo(pvaIn, commandID);
                            WpfConsole.Dispatcher.PostKey(keyInfo);
                            break;

                        case VSConstants.VSStd2KCmdID.CANCEL: // Handle ESC
                            WpfConsole.Dispatcher.CancelWaitKey();
                            break;
                    }
                    hr = VSConstants.S_OK; // eat everything
                }
                else
                {
                    switch (commandID)
                    {
                        case VSConstants.VSStd2KCmdID.TYPECHAR:
                            if (IsCompletionSessionActive)
                            {
                                char ch = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
                                if (IsCommitChar(ch))
                                {
                                    if (_completionSession.SelectedCompletionSet.SelectionStatus.IsSelected)
                                    {
                                        _completionSession.Commit();
                                    }
                                    else
                                    {
                                        _completionSession.Dismiss();
                                    }
                                }
                            }
                            else
                            {
                                if (IsSelectionReadonly)
                                {
                                    WpfTextView.Selection.Clear();
                                }
                                if (IsCaretInReadOnlyRegion)
                                {
                                    WpfTextView.Caret.MoveTo(WpfConsole.InputLineExtent.End);
                                }
                            }
                            break;

                        case VSConstants.VSStd2KCmdID.LEFT:
                        case VSConstants.VSStd2KCmdID.LEFT_EXT:
                        case VSConstants.VSStd2KCmdID.LEFT_EXT_COL:
                        case VSConstants.VSStd2KCmdID.WORDPREV:
                        case VSConstants.VSStd2KCmdID.WORDPREV_EXT:
                        case VSConstants.VSStd2KCmdID.WORDPREV_EXT_COL:
                            if (IsCaretAtInputLineStart)
                            {
                                //
                                // Note: This simple implementation depends on Prompt containing a trailing space.
                                // When caret is on the right of InputLineStart, editor will handle it correctly,
                                // and caret won't move left to InputLineStart because of the trailing space.
                                //
                                hr = VSConstants.S_OK; // eat it
                            }
                            break;

                        case VSConstants.VSStd2KCmdID.BOL:
                        case VSConstants.VSStd2KCmdID.BOL_EXT:
                        case VSConstants.VSStd2KCmdID.BOL_EXT_COL:
                            if (IsCaretOnInputLine)
                            {
                                VirtualSnapshotPoint oldCaretPoint = WpfTextView.Caret.Position.VirtualBufferPosition;

                                WpfTextView.Caret.MoveTo(WpfConsole.InputLineStart.Value);
                                WpfTextView.Caret.EnsureVisible();

                                if ((VSConstants.VSStd2KCmdID)nCmdID == VSConstants.VSStd2KCmdID.BOL)
                                {
                                    WpfTextView.Selection.Clear();
                                }
                                else if ((VSConstants.VSStd2KCmdID)nCmdID != VSConstants.VSStd2KCmdID.BOL)
                                // extend selection
                                {
                                    VirtualSnapshotPoint anchorPoint = WpfTextView.Selection.IsEmpty
                                        ? oldCaretPoint.TranslateTo(
                                            WpfTextView.TextSnapshot)
                                        : WpfTextView.Selection.AnchorPoint;
                                    WpfTextView.Selection.Select(anchorPoint,
                                        WpfTextView.Caret.Position.VirtualBufferPosition);
                                }

                                hr = VSConstants.S_OK;
                            }
                            break;

                        case VSConstants.VSStd2KCmdID.UP:
                            if (!IsCompletionSessionActive)
                            {
                                if (IsCaretInReadOnlyRegion)
                                {
                                    ExecuteCommand(VSConstants.VSStd2KCmdID.END);
                                }
                                WpfConsole.NavigateHistory(-1);
                                hr = VSConstants.S_OK;
                            }
                            break;

                        case VSConstants.VSStd2KCmdID.DOWN:
                            if (!IsCompletionSessionActive)
                            {
                                if (IsCaretInReadOnlyRegion)
                                {
                                    ExecuteCommand(VSConstants.VSStd2KCmdID.END);
                                }
                                WpfConsole.NavigateHistory(+1);
                                hr = VSConstants.S_OK;
                            }
                            break;

                        case VSConstants.VSStd2KCmdID.RETURN:
                            if (IsCompletionSessionActive)
                            {
                                if (_completionSession.SelectedCompletionSet.SelectionStatus.IsSelected)
                                {
                                    _completionSession.Commit();
                                }
                                else
                                {
                                    _completionSession.Dismiss();
                                }
                            }
                            else if (IsCaretOnInputLine || !IsCaretInReadOnlyRegion)
                            {
                                ExecuteCommand(VSConstants.VSStd2KCmdID.END);
                                ExecuteCommand(VSConstants.VSStd2KCmdID.RETURN);

                                NuGetUIThreadHelper.JoinableTaskFactory
                                    .RunAsync(() => EndInputLineAsync(WpfConsole))
                                    .PostOnFailure(nameof(WpfConsoleKeyProcessor));
                            }
                            hr = VSConstants.S_OK;
                            break;

                        case VSConstants.VSStd2KCmdID.TAB:
                            if (!IsCaretInReadOnlyRegion)
                            {
                                if (IsCompletionSessionActive)
                                {
                                    _completionSession.Commit();
                                }
                                else
                                {
                                    NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async delegate { await TriggerCompletionAsync(); })
                                                                           .PostOnFailure(nameof(WpfConsoleKeyProcessor));
                                }
                            }
                            hr = VSConstants.S_OK;
                            break;

                        case VSConstants.VSStd2KCmdID.CANCEL:
                            if (IsCompletionSessionActive)
                            {
                                _completionSession.Dismiss();
                                hr = VSConstants.S_OK;
                            }
                            else if (!IsCaretInReadOnlyRegion)
                            {
                                // Delete all text after InputLineStart
                                WpfTextView.TextBuffer.Delete(WpfConsole.AllInputExtent);
                                hr = VSConstants.S_OK;
                            }
                            break;
                        case VSConstants.VSStd2KCmdID.CUTLINE:
                            // clears the console when CutLine shortcut key is pressed,
                            // usually it is Ctrl + L
                            WpfConsole.ClearConsole();
                            hr = VSConstants.S_OK;
                            break;
                    }
                }
            }
            return hr;
        }