public void OnCommand()

in vsintegration/src/FSharp.LanguageService.Base/Source.cs [951:1033]


        public void OnCommand(IVsTextView textView, VsCommands2K command, char ch)
        {
            if (textView == null || this.service == null || !this.service.Preferences.EnableCodeSense)
                return;

            bool backward = (command == VsCommands2K.BACKSPACE || command == VsCommands2K.BACKTAB || command == VsCommands2K.LEFT || command == VsCommands2K.LEFT_EXT);

            int line, idx;

            var hr = textView.GetCaretPos(out line, out idx);
            if (NativeMethods.Failed(hr))
                return;

            TokenInfo info = GetTokenInfo(line, idx);
            TokenTriggers triggerClass = info.Trigger;


            var matchBraces = false;
            var methodTip = false;
            MethodTipMiscellany_DEPRECATED misc = 0;

            if ((triggerClass & TokenTriggers.MemberSelect) != 0 && (command == VsCommands2K.TYPECHAR))
            {
                BackgroundRequestReason reason = ((triggerClass & TokenTriggers.MatchBraces) != 0) ? BackgroundRequestReason.MemberSelectAndHighlightBraces : BackgroundRequestReason.MemberSelect;
                this.Completion(textView, info, reason, RequireFreshResults.No);
            }
            else if (this.service.Preferences.EnableMatchBraces &&
                ((command != VsCommands2K.BACKSPACE) && ((command == VsCommands2K.TYPECHAR) || this.service.Preferences.EnableMatchBracesAtCaret)))
            {

                // For brace matching when the caret is before the opening brace, we need to check the token at next index
                TokenInfo nextInfo = GetTokenInfo(line, idx + 1); // ??? overflow
                TokenTriggers nextTriggerClass = nextInfo.Trigger;

                if (((nextTriggerClass & (TokenTriggers.MatchBraces)) != 0) || ((triggerClass & (TokenTriggers.MatchBraces)) != 0))
                    matchBraces = true;
            }

            if ((triggerClass & TokenTriggers.MethodTip) != 0   // open paren, close paren, or comma
                && (command == VsCommands2K.TYPECHAR))          // they typed it, not just arrowed over it
            {
                methodTip = true;

                misc = MethodTipMiscellany_DEPRECATED.JustPressedOpenParen;
                if ((triggerClass & TokenTriggers.ParameterNext) != 0)
                    misc = MethodTipMiscellany_DEPRECATED.JustPressedComma;
                if ((triggerClass & TokenTriggers.ParameterEnd) != 0)
                    misc = MethodTipMiscellany_DEPRECATED.JustPressedCloseParen;
            }
            else if (this.methodData.IsDisplayed)
            {
                if (command == VsCommands2K.BACKSPACE)
                {
                    // the may have just erased a paren or comma, need to re-parse
                    methodTip = true;
                    misc = MethodTipMiscellany_DEPRECATED.JustPressedBackspace;
                }
                else
                {
                    this.methodData.Refresh(MethodTipMiscellany_DEPRECATED.Typing);
                }
            }

            if (matchBraces && methodTip)
            {
                // matchBraces = true and methodTip = true

                // backward is true when command is one of these: VsCommands2K.BACKSPACE | VsCommands2K.BACKTAB | VsCommands2K.LEFT | VsCommands2K.LEFT_EXT (1)
                // matchBraces = true when command is not BACKSPACE => BACKSPACE is excluded from the set (1)
                // methodTip = true when command is TYPECHAR or BACKSPACE => BACKSPACE is already excluded and TYPECHAR is not contained in set (1)
                // ergo: backward is always false here
                Debug.Assert(!backward);
                MatchBracesAndMethodTip(textView, line, idx, misc, info);
            }
            else if (matchBraces)
            {
                MatchBraces(textView, line, idx, info);
            }
            else if (methodTip)
            {
                MethodTip(textView, line, (backward && idx > 0) ? idx - 1 : idx, info, misc, RequireFreshResults.No);
            }
        }