protected virtual int ExecCommand()

in vsintegration/src/FSharp.LanguageService.Base/ViewFilter.cs [648:702]


        protected virtual int ExecCommand(ref Guid guidCmdGroup, uint nCmdId, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) {

            this.autoCompleted = false;
            int rc = 0;
            if (this.IsExpansionUIActive) {
                // Pass it along to the expansion UI picker.
                return this.InnerExec(ref guidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut);
            }

            ExpansionProvider ep = GetExpansionProvider();
            if (ep != null && ep.InTemplateEditingMode ) {
                if (ep.HandlePreExec(ref guidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut))
                    return rc;
            }

            if (!HandlePreExec(ref guidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut) &&
                this.nextTarget != null) {

                // Pass it along the chain.
                int count = this.source.ChangeCount;
                rc = this.InnerExec(ref guidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut);
                if (!Microsoft.VisualStudio.ErrorHandler.Succeeded(rc))
                    return rc;

                bool bufferWasChanged = count != source.ChangeCount;

                if (this.autoCompleted) {
                    this.autoCompleted = false;
                    // See if completion set just completed, so we can do auto-completion synchronously.
                    CompletionSet cset = this.source.CompletionSet;
                    if (cset != null) {
                        if (this.autoCompletedNothing &&
                            this.wasCompletionActive && guidCmdGroup == typeof(VsCommands2K).GUID &&
                            nCmdId == (uint)VsCommands2K.RETURN) {
                            // This happens if the user typed ENTER while the CompletionSet was active,
                            // but selected nothing from the list.  In this case the ENTER key was gobbled up
                            // by the CompletionSet, and we want the ENTER key inserted into the buffer instead.
                            this.wasCompletionActive = false;
                            this.InnerExec(ref guidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut);
                        }
                    }
                    if (this.autoCompleteTypeChar) {
                        // Auto-complete typed a different char so we skip HandlePostExec in this case.
                        return rc;
                    }
                }

                if (ep != null && ep.InTemplateEditingMode ) {
                    if (ep.HandlePostExec(ref guidCmdGroup, nCmdId, nCmdexecopt, gotEnterKey, pvaIn, pvaOut))
                        return rc;
                }
                HandlePostExec(ref guidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut, bufferWasChanged);
            }
            return rc;
        }