Beispiel #1
0
        int IOleCommandTarget.Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            if (pguidCmdGroup == commandGroup && nCmdID == commandId)
            {
                targetCommand.Execute(null);
                return(VSConstants.S_OK);
            }

            return(next?.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut) ?? 0);
        }
        int IOleCommandTarget.Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            if (pguidCmdGroup == commandGroup && nCmdID == commandId)
            {
                Exec?.Invoke(this, EventArgs.Empty);
                return(0);
            }

            return(next?.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut) ?? 0);
        }
        int IOleCommandTarget.Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            if (pguidCmdGroup == Constants.VS2017CmdSet && nCmdID == Constants.GotoImplementationCmdId)
            {
                var caretPosition = _context.WpfTextView.Caret.Position.BufferPosition;
                var lyzer         = new CodeAnalyzer(_context.ServiceProvider);

                var result = lyzer.IsResourceDesignerProperty(caretPosition).Result;
                if (result.result)
                {
                    return(lyzer.FindResourceReferences(result.document, result.designerProperty));
                }
            }
            return(_nextCommandTarget?.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut) ?? VSConstants.S_OK);
        }
        protected override bool Execute(uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut, IOleCommandTarget nextCommandTarget)
        {
            var groupId = CommandGroupId;
            if (nextCommandTarget.Exec(ref groupId, nCmdID, nCmdexecopt, pvaIn, pvaOut) == VSConstants.S_OK)
            {
                // parse the content
                var tokenizer = new RwHtmlTokenizer();
                var text = TextView.TextSnapshot.GetText();
                tokenizer.Tokenize(new StringReader(text));
                var parser = new RwHtmlParser();
                var node = parser.Parse(tokenizer.Tokens);

                // prepare the metadata control resolver
                var completionSource = TextView.TextBuffer.Properties.GetProperty<RwHtmlCompletionSource>(typeof(RwHtmlCompletionSource));
                var metadataControlResolver = completionSource.MetadataControlResolver;
                metadataControlResolver.ReloadAllControls(completionSource.GetCompletionContext());

                try
                {
                    CompletionHelper.DTE.UndoContext.Open("Format RWHTML document");
                    var edit = TextView.TextBuffer.CreateEdit(EditOptions.None, null, null);

                    // fix the casing of all elements
                    var editText = new StringBuilder(text);
                    foreach (var element in node.EnumerateNodes().OfType<RwHtmlElementNode>())
                    {
                        FixElement(editText, metadataControlResolver, TextView.TextBuffer, element);
                    }
                    edit.Replace(0, editText.Length, editText.ToString());
                    edit.Apply();
                }
                finally
                {
                    CompletionHelper.DTE.UndoContext.Close();
                }
            }

            return true;
        }
        /// <summary>
        /// Try and process the KeyInput from the Exec method.  This method decides whether or not
        /// a key should be processed directly by IVimBuffer or if should be going through
        /// IOleCommandTarget.  Generally the key is processed by IVimBuffer but for many intellisense
        /// scenarios we want the key to be routed to Visual Studio directly.  Issues to consider
        /// here are ...
        ///
        ///  - How should the KeyInput participate in Macro playback?
        ///  - Does both VsVim and Visual Studio need to process the key (Escape mainly)
        ///
        /// </summary>
        private bool TryProcessWithBuffer(KeyInput keyInput)
        {
            // If the IVimBuffer can't process it then it doesn't matter
            if (!_vimBuffer.CanProcess(keyInput))
            {
                return(false);
            }

            // In the middle of a word completion session let insert mode handle the input.  It's
            // displaying the intellisense itself and this method is meant to let custom intellisense
            // operate normally
            if (_vimBuffer.ModeKind == ModeKind.Insert && _vimBuffer.InsertMode.ActiveWordCompletionSession.IsSome())
            {
                return(_vimBuffer.Process(keyInput).IsAnyHandled);
            }

            // If we are in a peek definition window and normal mode we need to let the Escape key
            // pass on to the next command target.  This is necessary to close the peek definition
            // window
            if (_vimBuffer.ModeKind == ModeKind.Normal &&
                _textView.Roles.Contains(VsVimConstants.TextViewRoleEmbeddedPeekTextView) &&
                keyInput == KeyInputUtil.EscapeKey)
            {
                return(false);
            }

            // The only time we actively intercept keys and route them through IOleCommandTarget
            // is when one of the IDisplayWindowBroker windows is active
            //
            // In those cases if the KeyInput is a command which should be handled by the
            // display window we route it through IOleCommandTarget to get the proper
            // experience for those features
            if (!_broker.IsAnyDisplayActive())
            {
                return(_vimBuffer.Process(keyInput).IsAnyHandled);
            }

            // Next we need to consider here are Key mappings.  The CanProcess and Process APIs
            // will automatically map the KeyInput under the hood at the IVimBuffer level but
            // not at the individual IMode.  Have to manually map here and test against the
            // mapped KeyInput
            if (!TryGetSingleMapping(keyInput, out KeyInput mapped))
            {
                return(_vimBuffer.Process(keyInput).IsAnyHandled);
            }

            bool handled;

            if (IsDisplayWindowKey(mapped))
            {
                // If the key which actually needs to be processed is a display window key, say
                // down, up, etc..., then forward it on to the next IOleCommandTarget.  It is responsible
                // for mapping that key to action against the display window
                handled = ErrorHandler.Succeeded(_nextOleCommandTarget.Exec(mapped));
            }
            else
            {
                // Intentionally using keyInput here and not mapped.  Process will do mapping on the
                // provided input hence we should be using the original keyInput here not mapped
                handled = _vimBuffer.Process(keyInput).IsAnyHandled;
            }

            // The Escape key should always dismiss the active completion session.  However Vim
            // itself is mostly ignorant of display windows and typically won't dismiss them
            // as part of processing Escape (one exception is insert mode).  Dismiss it here if
            // it's still active
            if (mapped.Key == VimKey.Escape && _broker.IsAnyDisplayActive())
            {
                _broker.DismissDisplayWindows();
            }

            return(handled);
        }
Beispiel #6
0
 public int Exec(ref Guid pguidCmdGroup, uint nCmdId, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
 {
     return(_commandTarget?.Exec(ref pguidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut) ?? (int)Constants.OLECMDERR_E_NOTSUPPORTED);
 }
Beispiel #7
0
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) {
            int hr;
            // disable JavaScript language services auto formatting features, this is because
            // they are not aware that we have an extra level of indentation
            if (pguidCmdGroup == VSConstants.VSStd2K) {
                JavaScriptOutliningTaggerProvider.OutliningTagger tagger;
                switch ((VSConstants.VSStd2KCmdID)nCmdID) {
                    case VSConstants.VSStd2KCmdID.FORMATSELECTION: FormatSelection(); return VSConstants.S_OK;
                    case VSConstants.VSStd2KCmdID.FORMATDOCUMENT: FormatDocument(); return VSConstants.S_OK;
                    case VSConstants.VSStd2KCmdID.RETURN:
                        if (_intellisenseStack.TopSession != null &&
                            _intellisenseStack.TopSession is ICompletionSession &&
                            !_intellisenseStack.TopSession.IsDismissed) {
                            ((ICompletionSession)_intellisenseStack.TopSession).Commit();
                        } else {
                            SnapshotPoint start, end;
                            var startEndFound = GetStartAndEndOfCurrentLine(out start, out end);

                            hr = _next.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);

                            if (startEndFound) {
                                FormatOnEnter(start, end);
                            }
                            return hr;
                        }
                        return VSConstants.S_OK;
                    case VSConstants.VSStd2KCmdID.TYPECHAR:
                        if (!_incSearch.IsActive) {
                            var ch = (char)(ushort)System.Runtime.InteropServices.Marshal.GetObjectForNativeVariant(pvaIn);
                            int res = _next.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);

                            switch (ch) {
                                case '}':
                                case ';':
                                    FormatAfterTyping(ch);
                                    break;
                            }

                            if (_activeSession != null && !_activeSession.IsDismissed) {
                                _activeSession.Filter();
                            }

                            return res;
                        }
                        break;
                    case VSConstants.VSStd2KCmdID.PASTE:
                        return Paste(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut, out hr);

                    case VSConstants.VSStd2KCmdID.COMMENT_BLOCK:
                    case VSConstants.VSStd2KCmdID.COMMENTBLOCK:
                        if (_textView.CommentOrUncommentBlock(comment: true)) {
                            return VSConstants.S_OK;
                        }
                        break;
                    case VSConstants.VSStd2KCmdID.UNCOMMENT_BLOCK:
                    case VSConstants.VSStd2KCmdID.UNCOMMENTBLOCK:
                        if (_textView.CommentOrUncommentBlock(comment: false)) {
                            return VSConstants.S_OK;
                        }
                        break;
                    case VSConstants.VSStd2KCmdID.OUTLN_STOP_HIDING_ALL:
                        tagger = _textView.GetOutliningTagger();
                        if (tagger != null) {
                            tagger.Disable();
                        }
                        // let VS get the event as well
                        break;
                    case VSConstants.VSStd2KCmdID.OUTLN_START_AUTOHIDING:
                        tagger = _textView.GetOutliningTagger();
                        if (tagger != null) {
                            tagger.Enable();
                        }
                        // let VS get the event as well
                        break;
                }
            } else if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97) {
                switch ((VSConstants.VSStd97CmdID)nCmdID) {
                    case VSConstants.VSStd97CmdID.GotoDefn: return GotoDefinition();
                    case VSConstants.VSStd97CmdID.FindReferences: return FindAllReferences();
                    case VSConstants.VSStd97CmdID.Paste:
                        return Paste(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut, out hr);
                }
            }

            return _next.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
        }
        public static void Tab(this IOleCommandTarget target)
        {
            var guid = VSConstants.VSStd2K;

            target.Exec(ref guid, (int)VSConstants.VSStd2KCmdID.TAB, 0, IntPtr.Zero, IntPtr.Zero);
        }
        public static void MemberList(this IOleCommandTarget target)
        {
            var guid = VSConstants.VSStd2K;

            ErrorHandler.ThrowOnFailure(target.Exec(ref guid, (int)VSConstants.VSStd2KCmdID.SHOWMEMBERLIST, 0, IntPtr.Zero, IntPtr.Zero));
        }
        private int PreLanguageCommandFilterExec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            var nextTarget = firstLanguageServiceCommandFilter ?? _editorServicesCommandFilter;

            if (pguidCmdGroup == Guids.InteractiveCommandSetId)
            {
                switch ((CommandIds)nCmdID)
                {
                case CommandIds.AbortExecution: _window.Evaluator.AbortExecution(); return(VSConstants.S_OK);

                case CommandIds.Reset: _window.Operations.ResetAsync(); return(VSConstants.S_OK);

                case CommandIds.SmartExecute: _window.Operations.ExecuteInput(); return(VSConstants.S_OK);

                case CommandIds.HistoryNext: _window.Operations.HistoryNext(); return(VSConstants.S_OK);

                case CommandIds.HistoryPrevious: _window.Operations.HistoryPrevious(); return(VSConstants.S_OK);

                case CommandIds.ClearScreen: _window.Operations.ClearView(); return(VSConstants.S_OK);

                case CommandIds.CopyCode:
                {
                    var operation = _window.Operations as IInteractiveWindowOperations2;
                    if (operation != null)
                    {
                        operation.CopyCode();
                    }
                    return(VSConstants.S_OK);
                }

                case CommandIds.SearchHistoryNext:
                    _window.Operations.HistorySearchNext();
                    return(VSConstants.S_OK);

                case CommandIds.SearchHistoryPrevious:
                    _window.Operations.HistorySearchPrevious();
                    return(VSConstants.S_OK);
                }
            }
            else if (pguidCmdGroup == VSConstants.VSStd2K)
            {
                switch ((VSConstants.VSStd2KCmdID)nCmdID)
                {
                case VSConstants.VSStd2KCmdID.RETURN:
                    if (_window.Operations.TrySubmitStandardInput())
                    {
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.SHOWCONTEXTMENU:
                    ShowContextMenu();
                    return(VSConstants.S_OK);
                }
            }
            else if (currentBufferCommandHandler != null && pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
            {
                // undo/redo support:
                switch ((VSConstants.VSStd97CmdID)nCmdID)
                {
                // TODO: remove (https://github.com/dotnet/roslyn/issues/5642)
                case VSConstants.VSStd97CmdID.FindReferences:
                    return(VSConstants.S_OK);

                case VSConstants.VSStd97CmdID.Undo:
                case VSConstants.VSStd97CmdID.MultiLevelUndo:
                case VSConstants.VSStd97CmdID.MultiLevelUndoList:
                case VSConstants.VSStd97CmdID.Redo:
                case VSConstants.VSStd97CmdID.MultiLevelRedo:
                case VSConstants.VSStd97CmdID.MultiLevelRedoList:
                    return(currentBufferCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
                }
            }

            int res = nextTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);

#if DUMP_COMMANDS
            DumpCmd("Exec", result, ref pguidCmdGroup, nCmdID, 0);
#endif
            return(res);
        }
Beispiel #11
0
        private int ExecWorker(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            // preprocessing
            if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
            {
                switch ((VSConstants.VSStd97CmdID)nCmdID)
                {
                case VSConstants.VSStd97CmdID.Paste:
                    if (!_pyService.AdvancedOptions.PasteRemovesReplPrompts)
                    {
                        // Not stripping prompts, so don't use our logic
                        break;
                    }
                    var beforePaste = _textView.TextSnapshot;
                    if (_editorOps.Paste())
                    {
                        var afterPaste = _textView.TextSnapshot;
                        var um         = _undoManagerProvider.GetTextBufferUndoManager(afterPaste.TextBuffer);
                        using (var undo = um.TextBufferUndoHistory.CreateTransaction(Strings.RemoveReplPrompts)) {
                            if (ReplPromptHelpers.RemovePastedPrompts(beforePaste, afterPaste))
                            {
                                undo.Complete();
                            }
                        }
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd97CmdID.GotoDefn: GotoDefinition(); return(VSConstants.S_OK);

                case VSConstants.VSStd97CmdID.FindReferences: FindAllReferences(); return(VSConstants.S_OK);
                }
            }
            else if (pguidCmdGroup == CommonConstants.Std2KCmdGroupGuid)
            {
                SnapshotPoint?pyPoint;
                switch ((VSConstants.VSStd2KCmdID)nCmdID)
                {
                case VSConstants.VSStd2KCmdID.RETURN:
                    pyPoint = _textView.GetPythonCaret();
                    if (pyPoint != null)
                    {
                        // https://github.com/Microsoft/PTVS/issues/241
                        // If the current line is a full line comment and we
                        // are splitting the text, automatically insert the
                        // comment marker on the new line.
                        var line     = pyPoint.Value.GetContainingLine();
                        var lineText = pyPoint.Value.Snapshot.GetText(line.Start, pyPoint.Value - line.Start);
                        int comment  = lineText.IndexOf('#');
                        if (comment >= 0 &&
                            pyPoint.Value < line.End &&
                            line.Start + comment < pyPoint.Value &&
                            string.IsNullOrWhiteSpace(lineText.Remove(comment))
                            )
                        {
                            int extra = lineText.Skip(comment + 1).TakeWhile(char.IsWhiteSpace).Count() + 1;
                            using (var edit = line.Snapshot.TextBuffer.CreateEdit()) {
                                edit.Insert(
                                    pyPoint.Value.Position,
                                    _textView.Options.GetNewLineCharacter() + lineText.Substring(0, comment + extra)
                                    );
                                edit.Apply();
                            }

                            return(VSConstants.S_OK);
                        }
                    }
                    break;

                case VSConstants.VSStd2KCmdID.FORMATDOCUMENT:
                    pyPoint = _textView.GetPythonCaret();
                    if (pyPoint != null)
                    {
                        FormatCode(new SnapshotSpan(pyPoint.Value.Snapshot, 0, pyPoint.Value.Snapshot.Length), false);
                    }
                    return(VSConstants.S_OK);

                case VSConstants.VSStd2KCmdID.FORMATSELECTION:
                    foreach (var span in _textView.BufferGraph.MapDownToFirstMatch(
                                 _textView.Selection.StreamSelectionSpan.SnapshotSpan,
                                 SpanTrackingMode.EdgeInclusive,
                                 EditorExtensions.IsPythonContent
                                 ))
                    {
                        FormatCode(span, true);
                    }
                    return(VSConstants.S_OK);

                case VSConstants.VSStd2KCmdID.SHOWMEMBERLIST:
                case VSConstants.VSStd2KCmdID.COMPLETEWORD:
                    var controller = _textView.Properties.GetProperty <IntellisenseController>(typeof(IntellisenseController));
                    if (controller != null)
                    {
                        IntellisenseController.ForceCompletions = true;
                        try {
                            controller.TriggerCompletionSession(
                                (VSConstants.VSStd2KCmdID)nCmdID == VSConstants.VSStd2KCmdID.COMPLETEWORD,
                                true
                                );
                        } finally {
                            IntellisenseController.ForceCompletions = false;
                        }
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.QUICKINFO:
                    controller = _textView.Properties.GetProperty <IntellisenseController>(typeof(IntellisenseController));
                    if (controller != null)
                    {
                        controller.TriggerQuickInfo();
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.PARAMINFO:
                    controller = _textView.Properties.GetProperty <IntellisenseController>(typeof(IntellisenseController));
                    if (controller != null)
                    {
                        controller.TriggerSignatureHelp();
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.OUTLN_STOP_HIDING_ALL:
                    _textView.GetOutliningTagger()?.Disable();
                    // let VS get the event as well
                    break;

                case VSConstants.VSStd2KCmdID.OUTLN_START_AUTOHIDING:
                    _textView.GetOutliningTagger()?.Enable();
                    // let VS get the event as well
                    break;

                case VSConstants.VSStd2KCmdID.COMMENT_BLOCK:
                case VSConstants.VSStd2KCmdID.COMMENTBLOCK:
                    if (_textView.CommentOrUncommentBlock(comment: true))
                    {
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.UNCOMMENT_BLOCK:
                case VSConstants.VSStd2KCmdID.UNCOMMENTBLOCK:
                    if (_textView.CommentOrUncommentBlock(comment: false))
                    {
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.EXTRACTMETHOD:
                    ExtractMethod();
                    return(VSConstants.S_OK);

                case VSConstants.VSStd2KCmdID.RENAME:
                    RefactorRename();
                    return(VSConstants.S_OK);
                }
            }
            else if (pguidCmdGroup == GuidList.guidPythonToolsCmdSet)
            {
                switch (nCmdID)
                {
                case PkgCmdIDList.cmdidRefactorRenameIntegratedShell:
                    RefactorRename();
                    return(VSConstants.S_OK);

                case PkgCmdIDList.cmdidExtractMethodIntegratedShell:
                    ExtractMethod();
                    return(VSConstants.S_OK);

                case CommonConstants.StartDebuggingCmdId:
                case CommonConstants.StartWithoutDebuggingCmdId:
                    PythonToolsPackage.LaunchFile(_serviceProvider, _textView.GetFilePath(), nCmdID == CommonConstants.StartDebuggingCmdId, true);
                    return(VSConstants.S_OK);
                }
            }

            return(_next.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
        }
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            try
            {
                if (VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider))
                {
                    return(m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
                }

                // make a copy of this so we can look at it after forwarding some commands
                uint commandID = nCmdID;
                char typedChar = char.MinValue;

                // make sure the input is a char before getting it
                if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
                {
                    typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
                }

                // check for the triple slash
                if (typedChar == '/' && m_dte != null)
                {
                    string currentLine = m_textView.TextSnapshot.GetLineFromPosition(
                        m_textView.Caret.Position.BufferPosition.Position).GetText();
                    if ((currentLine + "/").Trim() == "///")
                    {
                        // Calculate how many spaces
                        string        spaces    = currentLine.Replace(currentLine.TrimStart(), "");
                        TextSelection ts        = m_dte.ActiveDocument.Selection as TextSelection;
                        int           oldLine   = ts.ActivePoint.Line;
                        int           oldOffset = ts.ActivePoint.LineCharOffset;
                        ts.LineDown();
                        ts.EndOfLine();

                        CodeElement   codeElement = null;
                        FileCodeModel fcm         = m_dte.ActiveDocument.ProjectItem.FileCodeModel;
                        if (fcm != null)
                        {
                            codeElement = fcm.CodeElementFromPoint(ts.ActivePoint, vsCMElement.vsCMElementFunction);
                        }

                        ts.MoveToLineAndOffset(oldLine, oldOffset - 2);
                        ts.Delete(2);

                        if (codeElement != null && codeElement is CodeFunction)
                        {
                            ts.Insert(createJavaStyleComment(codeElement, spaces));

                            ts.MoveToLineAndOffset(oldLine, oldOffset);
                            ts.LineDown();
                            ts.EndOfLine();
                            return(VSConstants.S_OK);
                        }
                        else
                        {
                            ts.Insert("/**\r\n" + spaces + "* \r\n" + spaces + "* \r\n" + spaces + "*/");
                            ts.MoveToLineAndOffset(oldLine, oldOffset);
                            ts.LineDown();
                            ts.EndOfLine();
                            return(VSConstants.S_OK);
                        }
                    }
                }

                if (m_session != null && !m_session.IsDismissed)
                {
                    // check for a commit character
                    if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN ||
                        nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB ||
                        typedChar == '>')
                    {
                        // check for a selection
                        // if the selection is fully selected, commit the current session
                        if (m_session.SelectedCompletionSet.SelectionStatus.IsSelected)
                        {
                            string selectedCompletion = m_session.SelectedCompletionSet.SelectionStatus.Completion.DisplayText;
                            m_session.Commit();
                            TextSelection ts = m_dte.ActiveDocument.Selection as TextSelection;
                            switch (selectedCompletion)
                            {
                            case "<!-->":
                                ts.CharLeft(false, 3);
                                break;

                            case "<![CDATA[>":
                                ts.CharLeft(false, 3);
                                break;

                            case "<c>":
                                ts.CharLeft(false, 4);
                                break;

                            case "<code>":
                                ts.CharLeft(false, 7);
                                break;

                            case "<example>":
                                ts.CharLeft(false, 10);
                                break;

                            case "<exception>":
                                ts.CharLeft(false, 14);
                                break;

                            case "<include>":
                                ts.CharLeft(false, 21);
                                break;

                            case "<list>":
                                ts.CharLeft(false, 7);
                                break;

                            case "<para>":
                                ts.CharLeft(false, 7);
                                break;

                            case "<param>":
                                ts.CharLeft(false, 10);
                                break;

                            case "<paramref>":
                                ts.CharLeft(false, 13);
                                break;

                            case "<permission>":
                                ts.CharLeft(false, 15);
                                break;

                            case "<remarks>":
                                ts.CharLeft(false, 10);
                                break;

                            case "<returns>":
                                ts.CharLeft(false, 10);
                                break;

                            case "<see>":
                                ts.CharLeft(false, 3);
                                break;

                            case "<seealso>":
                                ts.CharLeft(false, 3);
                                break;

                            case "<typeparam>":
                                ts.CharLeft(false, 14);
                                break;

                            case "<value>":
                                ts.CharLeft(false, 8);
                                break;

                            default:
                                break;
                            }

                            // also, don't add the character to the buffer
                            return(VSConstants.S_OK);
                        }
                        else
                        {
                            // if there is no selection, dismiss the session
                            m_session.Dismiss();
                        }
                    }
                }
                else
                {
                    if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN)
                    {
                        string currentLine = m_textView.TextSnapshot.GetLineFromPosition(
                            m_textView.Caret.Position.BufferPosition.Position).GetText();
                        if (currentLine.TrimStart().StartsWith("///"))
                        {
                            TextSelection ts     = m_dte.ActiveDocument.Selection as TextSelection;
                            string        spaces = currentLine.Replace(currentLine.TrimStart(), "");
                            ts.Insert("\r\n" + spaces + "/// ");
                            return(VSConstants.S_OK);
                        }
                    }
                }

                // pass along the command so the char is added to the buffer
                int retVal = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
                if (typedChar == '<')
                {
                    string currentLine = m_textView.TextSnapshot.GetLineFromPosition(
                        m_textView.Caret.Position.BufferPosition.Position).GetText();
                    if (currentLine.TrimStart().StartsWith("///"))
                    {
                        if (m_session == null || m_session.IsDismissed) // If there is no active session, bring up completion
                        {
                            if (this.TriggerCompletion())
                            {
                                m_session.Filter();
                                return(VSConstants.S_OK);
                            }
                        }
                    }
                }
                else if (
                    commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE ||
                    commandID == (uint)VSConstants.VSStd2KCmdID.DELETE ||
                    char.IsLetter(typedChar))
                {
                    if (m_session != null && !m_session.IsDismissed) // the completion session is already active, so just filter
                    {
                        m_session.Filter();
                        return(VSConstants.S_OK);
                    }
                }

                return(retVal);
            }
            catch
            {
            }

            return(VSConstants.E_FAIL);
        }
Beispiel #13
0
        private int ExecWorker(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            // preprocessing
            if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
            {
                switch ((VSConstants.VSStd97CmdID)nCmdID)
                {
                case VSConstants.VSStd97CmdID.Paste:
                    if (!_editorServices.Python.AdvancedOptions.PasteRemovesReplPrompts)
                    {
                        // Not stripping prompts, so don't use our logic
                        break;
                    }
                    var beforePaste = _textView.TextSnapshot;
                    if (_editorServices.EditOperationsFactory.GetEditorOperations(_textView).Paste())
                    {
                        var afterPaste = _textView.TextSnapshot;
                        var um         = _editorServices.UndoManagerFactory.GetTextBufferUndoManager(afterPaste.TextBuffer);
                        using (var undo = um.TextBufferUndoHistory.CreateTransaction(Strings.RemoveReplPrompts)) {
                            if (ReplPromptHelpers.RemovePastedPrompts(beforePaste, afterPaste))
                            {
                                undo.Complete();
                            }
                        }
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd97CmdID.GotoDefn: GotoDefinition(); return(VSConstants.S_OK);

                case VSConstants.VSStd97CmdID.FindReferences: FindAllReferences(); return(VSConstants.S_OK);
                }
            }
            else if (pguidCmdGroup == VSConstants.VsStd12)
            {
                switch ((VSConstants.VSStd12CmdID)nCmdID)
                {
                case VSConstants.VSStd12CmdID.PeekDefinition:
                    if (_editorServices.PeekBroker != null &&
                        !_textView.Roles.Contains(PredefinedTextViewRoles.EmbeddedPeekTextView) &&
                        !_textView.Roles.Contains(PredefinedTextViewRoles.CodeDefinitionView))
                    {
                        _editorServices.PeekBroker.TriggerPeekSession(_textView, PredefinedPeekRelationships.Definitions.Name);
                        return(VSConstants.S_OK);
                    }
                    break;
                }
            }
            else if (pguidCmdGroup == CommonConstants.Std2KCmdGroupGuid)
            {
                SnapshotPoint?         pyPoint;
                IntellisenseController controller;
                switch ((VSConstants.VSStd2KCmdID)nCmdID)
                {
                case VSConstants.VSStd2KCmdID.RETURN:
                    pyPoint = _textView.GetPythonCaret();
                    if (pyPoint != null)
                    {
                        // https://github.com/Microsoft/PTVS/issues/241
                        // If the current line is a full line comment and we
                        // are splitting the text, automatically insert the
                        // comment marker on the new line.
                        var line     = pyPoint.Value.GetContainingLine();
                        var lineText = pyPoint.Value.Snapshot.GetText(line.Start, pyPoint.Value - line.Start);
                        int comment  = lineText.IndexOf('#');
                        if (comment >= 0 &&
                            pyPoint.Value < line.End &&
                            line.Start + comment < pyPoint.Value &&
                            string.IsNullOrWhiteSpace(lineText.Remove(comment))
                            )
                        {
                            int extra = lineText.Skip(comment + 1).TakeWhile(char.IsWhiteSpace).Count() + 1;
                            using (var edit = line.Snapshot.TextBuffer.CreateEdit()) {
                                edit.Insert(
                                    pyPoint.Value.Position,
                                    _textView.Options.GetNewLineCharacter() + lineText.Substring(0, comment + extra)
                                    );
                                edit.Apply();
                            }

                            return(VSConstants.S_OK);
                        }
                    }
                    break;

                case VSConstants.VSStd2KCmdID.FORMATDOCUMENT:
                    FormatDocumentAsync().DoNotWait();
                    return(VSConstants.S_OK);

                case VSConstants.VSStd2KCmdID.FORMATSELECTION:
                    FormatSelectionAsync().DoNotWait();
                    return(VSConstants.S_OK);

                case VSConstants.VSStd2KCmdID.SHOWMEMBERLIST:
                case VSConstants.VSStd2KCmdID.COMPLETEWORD:
                    if (_textView.Properties.TryGetProperty(typeof(IntellisenseController), out controller))
                    {
                        controller.TriggerCompletionSession(
                            (VSConstants.VSStd2KCmdID)nCmdID == VSConstants.VSStd2KCmdID.COMPLETEWORD,
                            '\0',
                            true
                            ).DoNotWait();
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.QUICKINFO:
                    if (_textView.Properties.TryGetProperty(typeof(IntellisenseController), out controller))
                    {
                        controller.TriggerQuickInfoAsync().DoNotWait();
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.PARAMINFO:
                    if (_textView.Properties.TryGetProperty(typeof(IntellisenseController), out controller))
                    {
                        controller.TriggerSignatureHelp();
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.OUTLN_STOP_HIDING_ALL:
                    _textView.GetOutliningTagger()?.Disable(_textView.TextSnapshot);
                    // let VS get the event as well
                    break;

                case VSConstants.VSStd2KCmdID.OUTLN_START_AUTOHIDING:
                    _textView.GetOutliningTagger()?.Enable(_textView.TextSnapshot);
                    // let VS get the event as well
                    break;

                case VSConstants.VSStd2KCmdID.COMMENT_BLOCK:
                case VSConstants.VSStd2KCmdID.COMMENTBLOCK:
                    if (_textView.CommentOrUncommentBlock(comment: true))
                    {
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.UNCOMMENT_BLOCK:
                case VSConstants.VSStd2KCmdID.UNCOMMENTBLOCK:
                    if (_textView.CommentOrUncommentBlock(comment: false))
                    {
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.EXTRACTMETHOD:
                    ExtractMethod();
                    return(VSConstants.S_OK);

                case VSConstants.VSStd2KCmdID.RENAME:
                    RefactorRename();
                    return(VSConstants.S_OK);
                }
            }
            else if (pguidCmdGroup == GuidList.guidPythonToolsCmdSet)
            {
                switch (nCmdID)
                {
                case PkgCmdIDList.cmdidRefactorRenameIntegratedShell:
                    RefactorRename();
                    return(VSConstants.S_OK);

                case PkgCmdIDList.cmdidExtractMethodIntegratedShell:
                    ExtractMethod();
                    return(VSConstants.S_OK);

                case CommonConstants.StartDebuggingCmdId:
                case CommonConstants.StartWithoutDebuggingCmdId:
                    PythonToolsPackage.LaunchFile(_editorServices.Site, _textView.GetFilePath(), nCmdID == CommonConstants.StartDebuggingCmdId, true);
                    return(VSConstants.S_OK);
                }
            }

            return(_next.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
        }
        int IOleCommandTarget.Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            return(_editorCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
        }
        /// <summary>
        /// Handles a new command.
        /// </summary>
        /// <param name="CommandGroupGuid">The GUID of the command group.</param>
        /// <param name="CommandID">The command ID.</param>
        /// <param name="ExecOptions">Not used.</param>
        /// <param name="InputArgs">The input arguments of the command.</param>
        /// <param name="OutputArgs">The output arguments of the command.</param>
        /// <returns>A status code, either S_OK on a successful command exection or some other
        /// code that describes what happened if the command failed.</returns>
        public int Exec(ref Guid CommandGroupGuid, uint CommandID, uint ExecOptions, IntPtr InputArgs, IntPtr OutputArgs)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            try
            {
                // If we're in an automation function, we don't actually need to do anything.
                if (VsShellUtilities.IsInAutomationFunction(Provider.ServiceProvider))
                {
                    return(NextCommandHandler.Exec(ref CommandGroupGuid, CommandID, ExecOptions, InputArgs, OutputArgs));
                }

                // Get the character that was just typed (if there was one)
                char typedChar = char.MinValue;
                if (CommandGroupGuid == VSConstants.VSStd2K &&
                    CommandID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
                {
                    typedChar = (char)Marshal.GetObjectForNativeVariant <ushort>(InputArgs);
                }

                // Check if the user just entered a triple slash
                if (typedChar == '/' && Dte != null)
                {
                    if (UserTypedTripleSlash())
                    {
                        Logger.Debug("User entered a triple slash, handling it...");
                        HandleTripleSlash();
                        return(VSConstants.S_OK);
                    }
                }

                // Check if there's an autocomplete session open and the user just tried to accept one
                // of the autocomplete suggestions
                else if (MarkdownCompletionSession?.IsDismissed == false)
                {
                    if (CommandID == (uint)VSConstants.VSStd2KCmdID.RETURN ||
                        CommandID == (uint)VSConstants.VSStd2KCmdID.TAB)
                    {
                        if (MarkdownCompletionSession.SelectedCompletionSet.SelectionStatus.IsSelected)
                        {
                            Logger.Debug("User selected a Markdown header autocompletion suggestion.");
                            MarkdownCompletionSession.Commit();
                            return(VSConstants.S_OK);
                        }
                    }
                }

                // Handle the user pressing enter inside of a comment
                else if (CommandGroupGuid == VSConstants.VSStd2K &&
                         CommandID == (uint)VSConstants.VSStd2KCmdID.RETURN)
                {
                    if (HandleNewlineInCommentBlock())
                    {
                        Logger.Debug("User added a new line to a comment block.");
                        return(VSConstants.S_OK);
                    }
                }

                // If none of the above happened, pass the event onto the regular handler.
                int nextCommandResult = NextCommandHandler.Exec(ref CommandGroupGuid, CommandID, ExecOptions, InputArgs, OutputArgs);

                // Check to see if the user typed "#" so we need to start an autocomplete session
                if (typedChar == '#')
                {
                    string currentLine = TextView.TextSnapshot.GetLineFromPosition(
                        TextView.Caret.Position.BufferPosition.Position).GetText();
                    if (currentLine.TrimStart().StartsWith("/// #"))
                    {
                        // Create a new autocompletion session if there isn't one already
                        Logger.Debug("User entered # on a triple-slashed line, starting a new autocomplete session...");
                        if (MarkdownCompletionSession == null || MarkdownCompletionSession.IsDismissed)
                        {
                            if (StartMarkdownAutocompleteSession())
                            {
                                MarkdownCompletionSession.SelectedCompletionSet.SelectBestMatch();
                                MarkdownCompletionSession.SelectedCompletionSet.Recalculate();
                                return(VSConstants.S_OK);
                            }
                        }
                    }
                }

                // Check if there's an active autocomplete session, and the user just modified the text
                // in the editor
                else if (CommandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE ||
                         CommandID == (uint)VSConstants.VSStd2KCmdID.DELETE ||
                         char.IsLetter(typedChar))
                {
                    if (MarkdownCompletionSession?.IsDismissed == false)
                    {
                        MarkdownCompletionSession.SelectedCompletionSet.SelectBestMatch();
                        MarkdownCompletionSession.SelectedCompletionSet.Recalculate();
                        return(VSConstants.S_OK);
                    }
                }

                return(nextCommandResult);
            }
            catch (Exception ex)
            {
                Logger.Error($"Error handling command: {ex.GetType().Name} - {ex.Message}");
                Logger.Trace(ex.StackTrace);
                return(VSConstants.E_FAIL);
            }
        }
        private int PreLanguageCommandFilterExec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            var nextTarget = firstLanguageServiceCommandFilter ?? _editorServicesCommandFilter;

            if (pguidCmdGroup == Guids.InteractiveCommandSetId)
            {
                switch ((CommandIds)nCmdID)
                {
                case CommandIds.AbortExecution: _window.AbortCommand(); return(VSConstants.S_OK);

                case CommandIds.Reset: _window.Operations.ResetAsync(); return(VSConstants.S_OK);

                case CommandIds.SmartExecute: _window.Operations.ExecuteInput(); return(VSConstants.S_OK);

                case CommandIds.HistoryNext: _window.Operations.HistoryNext(); return(VSConstants.S_OK);

                case CommandIds.HistoryPrevious: _window.Operations.HistoryPrevious(); return(VSConstants.S_OK);

                case CommandIds.ClearScreen: _window.Operations.ClearView(); return(VSConstants.S_OK);

                case CommandIds.SearchHistoryNext:
                    _window.Operations.HistorySearchNext();
                    return(VSConstants.S_OK);

                case CommandIds.SearchHistoryPrevious:
                    _window.Operations.HistorySearchPrevious();
                    return(VSConstants.S_OK);
                }
            }
            else if (pguidCmdGroup == VSConstants.VSStd2K)
            {
                switch ((VSConstants.VSStd2KCmdID)nCmdID)
                {
                case VSConstants.VSStd2KCmdID.TYPECHAR:
                    _window.Operations.Delete();
                    break;

                case VSConstants.VSStd2KCmdID.RETURN:
                    if (_window.Operations.TrySubmitStandardInput())
                    {
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.SHOWCONTEXTMENU:
                    ShowContextMenu();
                    return(VSConstants.S_OK);
                }
            }
            else if (currentBufferCommandHandler != null && pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
            {
                // undo/redo support:
                switch ((VSConstants.VSStd97CmdID)nCmdID)
                {
                case VSConstants.VSStd97CmdID.Undo:
                case VSConstants.VSStd97CmdID.MultiLevelUndo:
                case VSConstants.VSStd97CmdID.MultiLevelUndoList:
                case VSConstants.VSStd97CmdID.Redo:
                case VSConstants.VSStd97CmdID.MultiLevelRedo:
                case VSConstants.VSStd97CmdID.MultiLevelRedoList:
                    return(currentBufferCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
                }
            }

            int res = nextTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);

#if DUMP_COMMANDS
            DumpCmd("Exec", result, ref pguidCmdGroup, nCmdID, 0);
#endif
            return(res);
        }
Beispiel #17
0
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            char typedChar = char.MinValue;
            int  result    = VSConstants.S_OK;
            Guid cmdGroup  = pguidCmdGroup;

            ThreadHelper.ThrowIfNotOnUIThread();

            // 1. Pre-process

            if (XSettings.DisableParameterInfo)
            {
                ;
            }
            else if (pguidCmdGroup == VSConstants.VSStd2K)
            {
                switch (nCmdID)
                {
                case (int)VSConstants.VSStd2KCmdID.PARAMINFO:
                    StartSignatureSession(true);
                    break;

                case (int)VSConstants.VSStd2KCmdID.COMPLETEWORD:
                case (int)VSConstants.VSStd2KCmdID.AUTOCOMPLETE:
                case (int)VSConstants.VSStd2KCmdID.SHOWMEMBERLIST:
                    CancelSignatureSession();
                    break;

                case (int)VSConstants.VSStd2KCmdID.BACKSPACE:
                    if (_signatureSession != null)
                    {
                        int pos = _textView.Caret.Position.BufferPosition;
                        if (pos > 0)
                        {
                            // get previous char
                            var previous = _textView.TextBuffer.CurrentSnapshot.GetText().Substring(pos - 1, 1);
                            if (previous == "(" || previous == "{")
                            {
                                _signatureSession.Dismiss();
                            }
                        }
                    }
                    break;
                }
            }
            else if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
            {
                switch (nCmdID)
                {
                case (int)VSConstants.VSStd97CmdID.Undo:
                case (int)VSConstants.VSStd97CmdID.Redo:
                    CancelSignatureSession();
                    break;
                }
            }
            var completionActive = IsCompletionActive();

            // 2. Let others do their thing
            result = m_nextCommandHandler.Exec(ref cmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
            // 3. Post process
            if (ErrorHandler.Succeeded(result) && !XSettings.DisableParameterInfo)
            {
                if (pguidCmdGroup == VSConstants.VSStd2K)
                {
                    switch (nCmdID)
                    {
                    case (int)VSConstants.VSStd2KCmdID.TYPECHAR:
                        typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
                        switch (typedChar)
                        {
                        case '(':
                        case '{':
                            CancelSignatureSession();
                            StartSignatureSession(false, triggerchar: typedChar);
                            break;

                        case ')':
                        case '}':
                            CancelSignatureSession();
                            if (hasopenSignatureSession())
                            {
                                StartSignatureSession(false, triggerchar: typedChar);
                            }
                            break;

                        case ',':
                            StartSignatureSession(true, triggerchar: typedChar);
                            //MoveSignature();
                            break;

                        case ':':
                        case '.':
                            CancelSignatureSession();
                            break;
                        }
                        break;

                    case (int)VSConstants.VSStd2KCmdID.RETURN:
                        if (!completionActive)
                        {
                            CancelSignatureSession();
                        }
                        break;

                    case (int)VSConstants.VSStd2KCmdID.LEFT:
                    case (int)VSConstants.VSStd2KCmdID.RIGHT:
                        MoveSignature();
                        break;
                    }
                }
            }
            return(result);
        }
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            if (VsShellUtilities.IsInAutomationFunction(_provider.ServiceProvider))
            {
                return(_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
            }

            if (IsStringOrComment())
            {
                this.Cancel();
                return(_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
            }

            int  retVal = VSConstants.S_OK;
            bool itIsCompletionSession = false;
            uint commandID             = nCmdID; //make a copy of this so we can look at it after forwarding some commands
            char typedChar             = char.MinValue;

            if (pguidCmdGroup == VSConstants.VSStd2K)
            {
                switch ((VSConstants.VSStd2KCmdID)nCmdID)
                {
                case VSConstants.VSStd2KCmdID.AUTOCOMPLETE:
                case VSConstants.VSStd2KCmdID.COMPLETEWORD:
                    itIsCompletionSession = this.StartSession();
                    break;

                case VSConstants.VSStd2KCmdID.RETURN: //commit char
                case VSConstants.VSStd2KCmdID.TAB:    //commit char
                    itIsCompletionSession = this.Commit();
                    break;

                case VSConstants.VSStd2KCmdID.CANCEL:
                    itIsCompletionSession = this.Cancel();
                    break;

                case VSConstants.VSStd2KCmdID.TYPECHAR:
                    typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
                    if (char.IsWhiteSpace(typedChar) || NotLetter(typedChar))
                    {
                        itIsCompletionSession = this.Cancel();
                    }

                    break;
                }
            }

            if (!itIsCompletionSession) // pass along the command so the char is added to the buffer
            {
                retVal = _nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
            }


            switch ((VSConstants.VSStd2KCmdID)nCmdID)
            {
            case VSConstants.VSStd2KCmdID.TYPECHAR:
                if (!NotLetter(typedChar) && !char.IsWhiteSpace(typedChar))
                {
                    if (_currentSession == null || _currentSession.IsDismissed) // If there is no active session, bring up completion
                    {
                        if (StartSession())
                        {
                            _currentSession.Filter();
                        }
                    }
                    else //the completion session is already active, so just filter
                    {
                        _currentSession.Filter();
                    }

                    itIsCompletionSession = true;
                }

                break;

            case VSConstants.VSStd2KCmdID.BACKSPACE:
            case VSConstants.VSStd2KCmdID.DELETE: // redo the filter if there is a deletion
                if (_currentSession != null && !_currentSession.IsDismissed)
                {
                    _currentSession.Filter();
                }

                itIsCompletionSession = true;
                break;
            }

            if (itIsCompletionSession)
            {
                return(VSConstants.S_OK);
            }

            return(retVal);
        }
Beispiel #19
0
 /// <summary>
 /// Called from VS when we should handle a command or pass it on.
 /// </summary>
 public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
 {
     return(_next.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
 }
Beispiel #20
0
        /// <summary>
        /// Called from VS when we should handle a command or pass it on.
        /// </summary>
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            if (IntellisenseControllerProvider.Instance != null &&
                IntellisenseControllerProvider.Instance.GeneroCommandTarget != null &&
                pguidCmdGroup == IntellisenseControllerProvider.Instance.GeneroCommandTarget.PackageGuid)
            {
                if (_textView != null && _textView.TextBuffer != null)
                {
                    string path = _textView.TextBuffer.GetFilePath();
                    if (IntellisenseControllerProvider.Instance.GeneroCommandTarget.Exec(path, nCmdID))
                    {
                        return(VSConstants.S_OK);
                    }
                }
            }

            // preprocessing
            if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
            {
                switch ((VSConstants.VSStd97CmdID)nCmdID)
                {
                case VSConstants.VSStd97CmdID.Paste:
                    //PythonReplEvaluator eval;
                    //if (_textView.Properties.TryGetProperty(typeof(PythonReplEvaluator), out eval))
                    //{
                    //    string pasting = eval.FormatClipboard() ?? Clipboard.GetText();
                    //    if (pasting != null)
                    //    {
                    //        PasteReplCode(eval, pasting);

                    //        return VSConstants.S_OK;
                    //    }
                    //}
                    //else
                    //{
                    //    string updated = RemoveReplPrompts(_textView.Options.GetNewLineCharacter());
                    //    if (updated != null)
                    //    {
                    //        _editorOps.ReplaceSelection(updated);
                    //        return VSConstants.S_OK;
                    //    }
                    //}
                    break;

                case VSConstants.VSStd97CmdID.GotoDefn: return(GotoDefinition());

                case VSConstants.VSStd97CmdID.FindReferences: return(FindAllReferences());
                }
            }
            else if (pguidCmdGroup == VSGeneroConstants.Std2KCmdGroupGuid)
            {
                OutliningTaggerProvider.OutliningTagger tagger;
                IntellisenseController controller = null;

                switch ((VSConstants.VSStd2KCmdID)nCmdID)
                {
                case (VSConstants.VSStd2KCmdID) 147:    // ECMD_SMARTTASKS  defined in stdidcmd.h, but not in MPF
                    // if the user is typing to fast for us to update the smart tags on the idle event
                    // then we want to update them before VS pops them up.
                    UpdateSmartTags();
                    break;

                //case VSConstants.VSStd2KCmdID.FORMATDOCUMENT:
                //    FormatCode(new SnapshotSpan(_textView.TextBuffer.CurrentSnapshot, 0, _textView.TextBuffer.CurrentSnapshot.Length), false);
                //    return VSConstants.S_OK;
                case VSConstants.VSStd2KCmdID.FORMATSELECTION:
                    if (_textView != null)
                    {
                        FormatCode(_textView.Selection.StreamSelectionSpan.SnapshotSpan, true);
                    }
                    return(VSConstants.S_OK);

                case VSConstants.VSStd2KCmdID.SHOWMEMBERLIST:
                case VSConstants.VSStd2KCmdID.COMPLETEWORD:
                    if (_textView != null)
                    {
                        controller =
                            _textView.Properties.GetProperty <IntellisenseController>(typeof(IntellisenseController));

                        if (controller != null)
                        {
                            IntellisenseController.ForceCompletions = true;
                            try
                            {
                                controller.TriggerCompletionSession((VSConstants.VSStd2KCmdID)nCmdID == VSConstants.VSStd2KCmdID.COMPLETEWORD,
                                                                    (VSConstants.VSStd2KCmdID)nCmdID == VSConstants.VSStd2KCmdID.SHOWMEMBERLIST);
                            }
                            finally
                            {
                                IntellisenseController.ForceCompletions = false;
                            }
                            return(VSConstants.S_OK);
                        }
                    }
                    break;

                case VSConstants.VSStd2KCmdID.QUICKINFO:
                    if (_textView != null)
                    {
                        controller =
                            _textView.Properties.GetProperty <IntellisenseController>(typeof(IntellisenseController));
                        if (controller != null)
                        {
                            controller.TriggerQuickInfo();
                            return(VSConstants.S_OK);
                        }
                    }
                    break;

                case VSConstants.VSStd2KCmdID.PARAMINFO:
                    if (_textView != null)
                    {
                        controller =
                            _textView.Properties.GetProperty <IntellisenseController>(typeof(IntellisenseController));
                        if (controller != null)
                        {
                            controller.TriggerSignatureHelp();
                            return(VSConstants.S_OK);
                        }
                    }
                    break;

                case VSConstants.VSStd2KCmdID.OUTLN_STOP_HIDING_ALL:
                    tagger = _textView.GetOutliningTagger();
                    tagger?.Disable();
                    // let VS get the event as well
                    break;

                case VSConstants.VSStd2KCmdID.OUTLN_START_AUTOHIDING:
                    tagger = _textView.GetOutliningTagger();
                    tagger?.Enable();
                    // let VS get the event as well
                    break;

                case VSConstants.VSStd2KCmdID.COMMENT_BLOCK:
                case VSConstants.VSStd2KCmdID.COMMENTBLOCK:
                    if (VSGenero.EditorExtensions.EditorExtensions.CommentOrUncommentBlock(_textView, comment: true))
                    {
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.UNCOMMENT_BLOCK:
                case VSConstants.VSStd2KCmdID.UNCOMMENTBLOCK:
                    if (VSGenero.EditorExtensions.EditorExtensions.CommentOrUncommentBlock(_textView, comment: false))
                    {
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.EXTRACTMETHOD:
                    ExtractMethod();
                    return(VSConstants.S_OK);

                case VSConstants.VSStd2KCmdID.RENAME:
                    RefactorRename();
                    return(VSConstants.S_OK);
                }
            }

            try
            {
                return(_next.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
            }
            catch (Exception ex)
            {
                return(VSConstants.S_FALSE);
            }
        }
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            uint cmdID     = nCmdID;
            char typedChar = char.MinValue;

            if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
            {
                typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
            }

            if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN ||
                cmdID == (uint)VSConstants.VSStd2KCmdID.TAB)
            {
                if (completionSession != null && !completionSession.IsDismissed)
                {
                    if (completionSession.SelectedCompletionSet.SelectionStatus.IsSelected)
                    {
                        completionSession.Commit();
                        return(VSConstants.S_OK);
                    }
                    else
                    {
                        completionSession.Dismiss();
                    }
                }
            }

            int returnValue = nextCommandHandler.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);

            bool isHandled = false;

            if (!typedChar.Equals(char.MinValue))
            {
                if (completionSession == null || completionSession.IsDismissed)
                {
                    TriggerCompletion();
                    if (completionSession != null)
                    {
                        completionSession.Filter();
                    }
                }
                else
                {
                    completionSession.Filter();
                }

                isHandled = true;
            }
            else if (cmdID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE ||
                     cmdID == (uint)VSConstants.VSStd2KCmdID.DELETE)
            {
                if (completionSession != null && !completionSession.IsDismissed)
                {
                    completionSession.Filter();
                }

                isHandled = true;
            }

            if (isHandled)
            {
                return(VSConstants.S_OK);
            }

            return(returnValue);
        }
Beispiel #22
0
 int IOleCommandTarget.Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
 {
     return(_commandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
 }
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (int)VSConstants.VSStd2KCmdID.TYPECHAR)
            {
                var ch = (char)(ushort)System.Runtime.InteropServices.Marshal.GetObjectForNativeVariant(pvaIn);

                if (_activeSession != null && !_activeSession.IsDismissed)
                {
                    if (_activeSession.SelectedCompletionSet.SelectionStatus.IsSelected)
                    {
                        var completion = _activeSession.SelectedCompletionSet.SelectionStatus.Completion;

                        string committedBy = String.Empty;
                        if (_activeSession.SelectedCompletionSet.Moniker == CompletionSource.NodejsRequireCompletionSetMoniker)
                        {
                            if (completion.InsertionText.StartsWith("'"))   // require(
                            {
                                committedBy = ")";
                            }
                            else if (completion.InsertionText.EndsWith("'"))     // require('
                            {
                                committedBy = "'";
                            }
                            else if (completion.InsertionText.EndsWith("\""))     // require("
                            {
                                committedBy = "\"";
                            }
                        }
                        else
                        {
                            committedBy = NodejsPackage.Instance != null && NodejsPackage.Instance.IntellisenseOptionsPage.OnlyTabOrEnterToCommit ?
                                          string.Empty :
                                          NodejsConstants.DefaultIntellisenseCompletionCommittedBy;
                        }

                        if (committedBy.IndexOf(ch) != -1)
                        {
                            _activeSession.Commit();
                            if ((completion.InsertionText.EndsWith("'") && ch == '\'') ||
                                (completion.InsertionText.EndsWith("\"") && ch == '"'))
                            {
                                // https://nodejstools.codeplex.com/workitem/960
                                // ' triggers the completion, but we don't want to insert the quote.
                                return(VSConstants.S_OK);
                            }
                        }
                    }
                    else if (_activeSession.SelectedCompletionSet.Moniker.Equals(CompletionSource.NodejsRequireCompletionSetMoniker) && !IsRequireIdentifierChar(ch))
                    {
                        _activeSession.Dismiss();
                    }
                    else if (!_activeSession.SelectedCompletionSet.Moniker.Equals(CompletionSource.NodejsRequireCompletionSetMoniker) && !IsIdentifierChar(ch))
                    {
                        _activeSession.Dismiss();
                    }
                }

                int res = _oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);

                if (_activeSession == null || !_activeSession.SelectedCompletionSet.Moniker.Equals(CompletionSource.NodejsRequireCompletionSetMoniker))
                {
                    //Only process the char if we are not in a require completion
                    HandleChar((char)(ushort)System.Runtime.InteropServices.Marshal.GetObjectForNativeVariant(pvaIn));
                }

                if (_activeSession != null && !_activeSession.IsDismissed)
                {
                    _activeSession.Filter();
                }

                return(res);
            }

            if (_activeSession != null)
            {
                if (pguidCmdGroup == VSConstants.VSStd2K)
                {
                    switch ((VSConstants.VSStd2KCmdID)nCmdID)
                    {
                    case VSConstants.VSStd2KCmdID.RETURN:
                        if (/*NodejsPackage.Instance.AdvancedEditorOptionsPage.EnterCommitsIntellisense*/ true &&
                            !_activeSession.IsDismissed &&
                            _activeSession.SelectedCompletionSet.SelectionStatus.IsSelected)
                        {
                            // If the user has typed all of the characters as the completion and presses
                            // enter we should dismiss & let the text editor receive the enter.  For example
                            // when typing "import sys[ENTER]" completion starts after the space.  After typing
                            // sys the user wants a new line and doesn't want to type enter twice.

                            bool enterOnComplete = /*NodejsPackage.Instance.AdvancedEditorOptionsPage.AddNewLineAtEndOfFullyTypedWord*/ true &&
                                                   EnterOnCompleteText();

                            _activeSession.Commit();

                            if (!enterOnComplete)
                            {
                                return(VSConstants.S_OK);
                            }
                        }
                        else
                        {
                            _activeSession.Dismiss();
                        }
                        break;

                    case VSConstants.VSStd2KCmdID.TAB:
                        if (!_activeSession.IsDismissed)
                        {
                            _activeSession.Commit();
                            return(VSConstants.S_OK);
                        }
                        break;

                    case VSConstants.VSStd2KCmdID.BACKSPACE:
                    case VSConstants.VSStd2KCmdID.DELETE:
                    case VSConstants.VSStd2KCmdID.DELETEWORDLEFT:
                    case VSConstants.VSStd2KCmdID.DELETEWORDRIGHT:
                        int res = _oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
                        if (_activeSession != null && !_activeSession.IsDismissed)
                        {
                            _activeSession.Filter();
                        }
                        return(res);
                    }
                }
            }
            else if (_sigHelpSession != null)
            {
                if (pguidCmdGroup == VSConstants.VSStd2K)
                {
                    switch ((VSConstants.VSStd2KCmdID)nCmdID)
                    {
                    case VSConstants.VSStd2KCmdID.BACKSPACE:
                        bool fDeleted = Backspace();
                        if (fDeleted)
                        {
                            return(VSConstants.S_OK);
                        }
                        break;

                    case VSConstants.VSStd2KCmdID.LEFT:
                        _editOps.MoveToPreviousCharacter(false);
                        UpdateCurrentParameter();
                        return(VSConstants.S_OK);

                    case VSConstants.VSStd2KCmdID.RIGHT:
                        _editOps.MoveToNextCharacter(false);
                        UpdateCurrentParameter();
                        return(VSConstants.S_OK);

                    case VSConstants.VSStd2KCmdID.HOME:
                    case VSConstants.VSStd2KCmdID.BOL:
                    case VSConstants.VSStd2KCmdID.BOL_EXT:
                    case VSConstants.VSStd2KCmdID.EOL:
                    case VSConstants.VSStd2KCmdID.EOL_EXT:
                    case VSConstants.VSStd2KCmdID.END:
                    case VSConstants.VSStd2KCmdID.WORDPREV:
                    case VSConstants.VSStd2KCmdID.WORDPREV_EXT:
                    case VSConstants.VSStd2KCmdID.DELETEWORDLEFT:
                        _sigHelpSession.Dismiss();
                        _sigHelpSession = null;
                        break;
                    }
                }
            }
            if (pguidCmdGroup == VSConstants.VSStd2K)
            {
                switch ((VSConstants.VSStd2KCmdID)nCmdID)
                {
                case VSConstants.VSStd2KCmdID.QUICKINFO:
                    TriggerQuickInfo();
                    return(VSConstants.S_OK);

                case VSConstants.VSStd2KCmdID.PARAMINFO:
                    TriggerSignatureHelp();
                    return(VSConstants.S_OK);

                case VSConstants.VSStd2KCmdID.RETURN:
                    if (_expansionMgr != null && _expansionClient.InSession && ErrorHandler.Succeeded(_expansionClient.EndCurrentExpansion(false)))
                    {
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.TAB:
                    if (_expansionMgr != null && _expansionClient.InSession && ErrorHandler.Succeeded(_expansionClient.NextField()))
                    {
                        return(VSConstants.S_OK);
                    }
                    if (_textView.Selection.IsEmpty && _textView.Caret.Position.BufferPosition > 0)
                    {
                        if (TryTriggerExpansion())
                        {
                            return(VSConstants.S_OK);
                        }
                    }
                    break;

                case VSConstants.VSStd2KCmdID.BACKTAB:
                    if (_expansionMgr != null && _expansionClient.InSession && ErrorHandler.Succeeded(_expansionClient.PreviousField()))
                    {
                        return(VSConstants.S_OK);
                    }
                    break;

                case VSConstants.VSStd2KCmdID.SURROUNDWITH:
                case VSConstants.VSStd2KCmdID.INSERTSNIPPET:
                    TriggerSnippet(nCmdID);
                    return(VSConstants.S_OK);

                case VSConstants.VSStd2KCmdID.SHOWMEMBERLIST:
                case VSConstants.VSStd2KCmdID.COMPLETEWORD:
                    ForceCompletions = true;
                    try {
                        TriggerCompletionSession((VSConstants.VSStd2KCmdID)nCmdID == VSConstants.VSStd2KCmdID.COMPLETEWORD &&
                                                 !NodejsPackage.Instance.IntellisenseOptionsPage.OnlyTabOrEnterToCommit);
                    } finally {
                        ForceCompletions = false;
                    }
                    return(VSConstants.S_OK);
                }
            }
            return(_oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
        }
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            if (VsShellUtilities.IsInAutomationFunction(_provider.ServiceProvider))
            {
                return(_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
            }


            //make a copy of this so we can look at it after forwarding some commands
            uint commandID = nCmdID;
            char typedChar = char.MinValue;

            //make sure the input is a char before getting it
            if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
            {
                typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
            }

            if (typedChar == '.')
            {
                Console.WriteLine();
            }

            //check for a commit character
            if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN ||
                nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB ||
                (char.IsWhiteSpace(typedChar) || char.IsPunctuation(typedChar)))
            {
                //check for a a selection
                if (_session != null && !_session.IsDismissed)
                {
                    //if the selection is fully selected, commit the current session
                    if (_session.SelectedCompletionSet.SelectionStatus.IsSelected)
                    {
                        var completion = _session.SelectedCompletionSet.SelectionStatus.Completion;
                        if (completion.InsertionText != null &&
                            typedChar != ':' &&
                            (typedChar != '.' || !completion.InsertionText.Contains('.')))
                        {
                            _session.Commit();

                            if (completion.Properties.ContainsProperty("RecommendedCursorOffset"))
                            {
                                int offset = (int)completion.Properties["RecommendedCursorOffset"];

                                var currp = _textView.Caret.Position.BufferPosition;
                                var newp  = currp - (completion.InsertionText.Length - offset);

                                _textView.Caret.MoveTo(newp);
                            }

                            //also, don't add the character to the buffer
                            return(VSConstants.S_OK);
                        }
                        else
                        {
                            nCmdID = (uint)VSConstants.VSStd2KCmdID.COMPLETEWORD;
                        }
                    }
                    else
                    {
                        //if there is no selection, dismiss the session
                        _session.Dismiss();
                    }
                }
            }

            //pass along the command so the char is added to the buffer
            int  retVal  = VSConstants.S_OK;
            bool handled = false;

            if (nCmdID == (uint)VSConstants.VSStd2KCmdID.COMPLETEWORD ||
                (!typedChar.Equals(char.MinValue) &&
                 (char.IsLetterOrDigit(typedChar) || typedChar == '<' || typedChar == ' ' || typedChar == '.' || typedChar == ':')))
            {
                if (typedChar != '\0')
                {
                    if (typedChar == '.' || typedChar == ':' || typedChar == '<')
                    {
                        if (!_textView.Selection.IsEmpty)
                        {
                            foreach (var span in _textView.Selection.SelectedSpans.OrderByDescending(x => x.Start))
                            {
                                _textView.TextBuffer.Replace(span, "");
                            }
                        }
                        _textView.TextBuffer.Insert(_textView.Caret.Position.BufferPosition.Position,
                                                    typedChar.ToString());
                    }
                    else
                    {
                        retVal = _realCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
                    }
                }
                if (_session == null || _session.IsDismissed)
                // If there is no active session, bring up completion
                {
                    TriggerCompletion();
                    if (typedChar != '<' && typedChar != 0 && _session != null)
                    {
                        _session.Filter();
                    }
                }
                else
                {
                    _session.Filter();
                }
                handled = true;
            }
            else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || //redo the filter if there is a deletion
                     commandID == (uint)VSConstants.VSStd2KCmdID.DELETE)
            {
                if (_session != null && !_session.IsDismissed)
                {
                    _session.Filter();
                }
                retVal  = _nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
                handled = true;
            }

            else
            {
                retVal = _nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
            }
            if (handled)
            {
                return(VSConstants.S_OK);
            }
            return(retVal);
        }
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            if (VsShellUtilities.IsInAutomationFunction(_provider.ServiceProvider))
            {
                return(_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
            }

            uint commandID = nCmdID;
            char typedChar = char.MinValue;

            if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
            {
                typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
            }
            // return and tab command commit the session and return
            if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN ||
                nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB)
            {
                if (_session != null && !_session.IsDismissed)
                {
                    if (_session.SelectedCompletionSet.SelectionStatus.IsSelected)
                    {
                        _session.Commit();
                        return(VSConstants.S_OK);
                    }
                    else
                    {
                        _session.Dismiss();
                    }
                }
            }
            // whitespace and punctuation commit the session
            if (char.IsWhiteSpace(typedChar) || char.IsPunctuation(typedChar))
            {
                if (_session != null && !_session.IsDismissed)
                {
                    if (_session.SelectedCompletionSet.SelectionStatus.IsSelected)
                    {
                        _session.Commit();
                    }
                    else
                    {
                        _session.Dismiss();
                    }
                }
            }

            int  retVal  = _nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
            bool handled = false;

            if (!typedChar.Equals(char.MinValue) && char.IsLetterOrDigit(typedChar))
            {
                if (_session == null || _session.IsDismissed)
                {
                    this.TriggerCompletion();
                    if (_session != null)
                    {
                        _session.Filter();
                    }
                }
                else
                {
                    _session.Filter();
                }
                handled = true;
            }
            else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE ||
                     commandID == (uint)VSConstants.VSStd2KCmdID.DELETE)
            {
                if (_session != null && _session.IsDismissed)
                {
                    _session.Filter();
                }
                handled = true;
            }
            if (handled)
            {
                return(VSConstants.S_OK);
            }
            return(retVal);
        }
Beispiel #26
0
        /// <summary>
        /// Main method used to determine how to handle keystrokes within a ITextBuffer.
        /// </summary>
        /// <param name="pguidCmdGroup">The GUID of the command group.</param>
        /// <param name="nCmdId">The command ID.</param>
        /// <param name="nCmdexecopt">
        ///    Specifies how the object should execute the command. Possible values are taken from the
        ///    Microsoft.VisualStudio.OLE.Interop.OLECMDEXECOPT and Microsoft.VisualStudio.OLE.Interop.OLECMDID_WINDOWSTATE_FLAG
        ///    enumerations.
        /// </param>
        /// <param name="pvaIn">The input arguments of the command.</param>
        /// <param name="pvaOut">The output arguments of the command.</param>
        /// <returns></returns>
        public int Exec(ref Guid pguidCmdGroup, uint nCmdId, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            bool?isInStringArea = null;
            var  command        = (VSConstants.VSStd2KCmdID)nCmdId;

            if (VsShellUtilities.IsInAutomationFunction(_serviceProvider) ||
                IsUnhandledCommand(pguidCmdGroup, command) ||
                Utilities.IsCaretInCommentArea(_textView))
            {
                Log.DebugFormat("Non-VSStd2K command: '{0}'", ToCommandName(pguidCmdGroup, nCmdId));
                return(NextCommandHandler.Exec(ref pguidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut));
            }

            //make a copy of this so we can look at it after forwarding some commands
            var typedChar = char.MinValue;

            // Exit tab complete session if command is any recognized command other than tab
            if (_tabCompleteSession != null && command != VSConstants.VSStd2KCmdID.TAB && command != VSConstants.VSStd2KCmdID.BACKTAB)
            {
                _tabCompleteSession = null;
                _startTabComplete   = false;
            }

            //make sure the input is a char before getting it
            if (command == VSConstants.VSStd2KCmdID.TYPECHAR)
            {
                typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
                Log.DebugFormat("Typed Character: '{0}'", (typedChar == char.MinValue) ? "<null>" : typedChar.ToString());

                if (_activeSession == null &&
                    IsNotIntelliSenseTriggerWhenInStringLiteral(typedChar))
                {
                    isInStringArea = this.IsInStringArea(isInStringArea);
                    if (isInStringArea == true)
                    {
                        return(NextCommandHandler.Exec(ref pguidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut));
                    }
                }
            }
            else
            {
                Log.DebugFormat("Non-TypeChar command: '{0}'", ToCommandName(pguidCmdGroup, nCmdId));
            }

            switch (command)
            {
            case VSConstants.VSStd2KCmdID.RETURN:
                //check for a a selection
                if (_activeSession != null && !_activeSession.IsDismissed)
                {
                    //if the selection is fully selected, commit the current session
                    if (_activeSession.SelectedCompletionSet.SelectionStatus.IsSelected)
                    {
                        Log.Debug("Commit");
                        _activeSession.Commit();

                        //also, don't add the character to the buffer
                        return(VSConstants.S_OK);
                    }
                    else
                    {
                        Log.Debug("Dismiss");
                        //if there is no selection, dismiss the session
                        _activeSession.Dismiss();
                    }
                }
                break;

            case VSConstants.VSStd2KCmdID.TAB:
            case VSConstants.VSStd2KCmdID.BACKTAB:

                if (_activeSession != null && !_activeSession.IsDismissed)
                {
                    var completions = _activeSession.SelectedCompletionSet.Completions;
                    if (completions != null && completions.Count > 0)
                    {
                        var startPoint = _activeSession.SelectedCompletionSet.ApplicableTo.GetStartPoint(_textView.TextBuffer.CurrentSnapshot).Position;
                        _tabCompleteSession = new TabCompleteSession(_activeSession.SelectedCompletionSet.Completions, _activeSession.SelectedCompletionSet.SelectionStatus, startPoint);
                        _activeSession.Commit();

                        //also, don't add the character to the buffer
                        return(VSConstants.S_OK);
                    }
                    else
                    {
                        Log.Debug("Dismiss");
                        //If there are no completions, dismiss the session
                        _activeSession.Dismiss();
                    }
                }
                else if (_tabCompleteSession != null)
                {
                    if (command == VSConstants.VSStd2KCmdID.TAB)
                    {
                        _tabCompleteSession.ReplaceWithNextCompletion(_textView.TextBuffer, _textView.Caret.Position.BufferPosition.Position);
                    }
                    else
                    {
                        _tabCompleteSession.ReplaceWithPreviousCompletion(_textView.TextBuffer, _textView.Caret.Position.BufferPosition.Position);
                    }

                    //don't add the character to the buffer
                    return(VSConstants.S_OK);
                }
                else if (!Utilities.IsPrecedingTextInLineEmpty(_textView.Caret.Position.BufferPosition) && _textView.Selection.IsEmpty)
                {
                    _startTabComplete = true;
                    TriggerCompletion();

                    //don't add the character to the buffer
                    return(VSConstants.S_OK);
                }
                break;

            case VSConstants.VSStd2KCmdID.COMPLETEWORD:
                isInStringArea = this.IsInStringArea(isInStringArea);
                if (isInStringArea == true)
                {
                    return(NextCommandHandler.Exec(ref pguidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut));
                }

                TriggerCompletion();
                return(VSConstants.S_OK);

            default:
                break;
            }

            //check for a commit character
            if (char.IsWhiteSpace(typedChar) && _activeSession != null && !_activeSession.IsDismissed)
            {
                // If user is typing a variable, SPACE shouldn't commit the selection.
                // If the selection is fully matched with user's input, commit the current session and add the commit character to text buffer.
                if (_activeSession.SelectedCompletionSet.SelectionStatus.IsSelected &&
                    !_activeSession.SelectedCompletionSet.SelectionStatus.Completion.InsertionText.StartsWith("$", StringComparison.InvariantCulture))
                {
                    Log.Debug("Commit");
                    _activeSession.Commit();

                    bool isCompletionFullyMatched = false;
                    _textView.TextBuffer.Properties.TryGetProperty(BufferProperties.SessionCompletionFullyMatchedStatus, out isCompletionFullyMatched);
                    if (isCompletionFullyMatched)
                    {
                        // If user types all characters in a completion and click Space, then we should commit the selection and add the Space into text buffer.
                        return(NextCommandHandler.Exec(ref pguidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut));
                    }

                    //Don't add the character to the buffer if this commits the selection.
                    return(VSConstants.S_OK);
                }
                else
                {
                    Log.Debug("Dismiss");
                    //if there is no selection, dismiss the session
                    _activeSession.Dismiss();
                }
            }

            bool justCommitIntelliSense = false;

            if (IsIntelliSenseTriggerDot(typedChar) && _activeSession != null && !_activeSession.IsDismissed)
            {
                var selectionStatus = _activeSession.SelectedCompletionSet.SelectionStatus;
                if (selectionStatus.IsSelected)
                {
                    // If user types the full completion text, which ends with a dot, then we should just commit IntelliSense session ignore user's last typing.
                    ITrackingSpan lastWordSpan;
                    var           currentSnapshot = _textView.TextBuffer.CurrentSnapshot;
                    _textView.TextBuffer.Properties.TryGetProperty <ITrackingSpan>(BufferProperties.LastWordReplacementSpan, out lastWordSpan);
                    if (lastWordSpan != null)
                    {
                        string lastWordText        = lastWordSpan.GetText(currentSnapshot);
                        int    completionSpanStart = lastWordSpan.GetStartPoint(currentSnapshot);
                        int    completionSpanEnd   = _textView.Caret.Position.BufferPosition;
                        var    completionText      = currentSnapshot.GetText(completionSpanStart, completionSpanEnd - completionSpanStart);
                        completionText += typedChar;
                        Log.DebugFormat("completionSpanStart: {0}", completionSpanStart);
                        Log.DebugFormat("completionSpanEnd: {0}", completionSpanEnd);
                        Log.DebugFormat("completionText: {0}", completionText);

                        if (selectionStatus.Completion.InsertionText.Equals(completionText, StringComparison.OrdinalIgnoreCase))
                        {
                            Log.Debug(String.Format("Commited by {0}", typedChar));
                            _activeSession.Commit();
                            return(VSConstants.S_OK);
                        }
                    }

                    Log.Debug("Commit");
                    _activeSession.Commit();
                    justCommitIntelliSense = true;
                }
                else
                {
                    Log.Debug("Dismiss");
                    //if there is no selection, dismiss the session
                    _activeSession.Dismiss();
                }
            }

            // Check the char at caret before pass along the command
            // If command is backspace and completion session is active, then we need to see if the char to be deleted is an IntelliSense triggering char
            // If yes, then after deleting the char, we also dismiss the completion session
            // Otherwise, just filter the completion lists
            char charAtCaret = char.MinValue;

            if (command == VSConstants.VSStd2KCmdID.BACKSPACE && _activeSession != null && !_activeSession.IsDismissed)
            {
                int caretPosition = _textView.Caret.Position.BufferPosition.Position - 1;
                if (caretPosition >= 0)
                {
                    // caretPosition == -1 means caret is at the beginning of a file, which means no characters before it.
                    ITrackingPoint caretCharPosition = _textView.TextSnapshot.CreateTrackingPoint(caretPosition, PointTrackingMode.Positive);
                    charAtCaret = caretCharPosition.GetCharacter(_textView.TextSnapshot);
                }
            }

            // pass along the command so the char is added to the buffer
            int  retVal  = NextCommandHandler.Exec(ref pguidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut);
            bool handled = false;

            if (IsIntellisenseTrigger(typedChar) ||
                (justCommitIntelliSense || (IsIntelliSenseTriggerDot(typedChar) && IsPreviousTokenVariable())) || // If dot just commit a session or previous token before a dot was a variable, trigger intellisense
                (char.IsWhiteSpace(typedChar) && IsPreviousTokenParameter()))                                     // If the previous token before a space was a parameter, trigger intellisense
            {
                isInStringArea = this.IsInStringArea(isInStringArea);
                if (isInStringArea == false)
                {
                    TriggerCompletion();
                }
            }
            if (!typedChar.Equals(char.MinValue) && IsFilterTrigger(typedChar))
            {
                if (_activeSession != null)
                {
                    if (_activeSession.IsStarted)
                    {
                        try
                        {
                            Log.Debug("Filter");
                            _activeSession.Filter();
                        }
                        catch (Exception ex)
                        {
                            Log.Debug("Failed to filter session.", ex);
                        }
                    }
                }
            }
            else if (command == VSConstants.VSStd2KCmdID.BACKSPACE ||
                     command == VSConstants.VSStd2KCmdID.DELETE) //redo the filter if there is a deletion
            {
                if (_activeSession != null && !_activeSession.IsDismissed)
                {
                    try
                    {
                        if (_textView.Caret.Position.BufferPosition <= _completionCaretPosition)
                        {
                            Log.Debug("Dismiss");
                            _activeSession.Dismiss();
                        }
                        else
                        {
                            Log.Debug("Filter");
                            _activeSession.Filter();
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Debug("Failed to filter session.", ex);
                    }
                }

                handled = true;
            }
            if (handled)
            {
                return(VSConstants.S_OK);
            }
            return(retVal);
        }
        public static void Backspace(this IOleCommandTarget target)
        {
            var guid = VSConstants.VSStd2K;

            target.Exec(ref guid, (int)VSConstants.VSStd2KCmdID.BACKSPACE, 0, IntPtr.Zero, IntPtr.Zero);
        }
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            if (VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider))
            {
                return(m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
            }

            // Make a copy of this so we can look at it after forwarding some commands
            uint commandID = nCmdID;
            char typedChar = char.MinValue;

            // Make sure the input is a char before getting it
            if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
            {
                typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
            }

            // Check for a commit character
            if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN ||
                nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB ||
                char.IsWhiteSpace(typedChar))
            {
                // Check for a a selection
                if (m_session != null && !m_session.IsDismissed)
                {
                    // If the selection is fully selected, commit the current session
                    if (m_session.SelectedCompletionSet.SelectionStatus.IsSelected)
                    {
                        m_session.Commit( );
                        // Also, don't add the character to the buffer
                        return(VSConstants.S_OK);
                    }
                    else
                    {
                        // If there is no selection, dismiss the session
                        m_session.Dismiss( );
                    }
                }
            }

            //pass along the command so the char is added to the buffer
            int  retVal  = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
            bool handled = false;

            if (!typedChar.Equals(char.MinValue) && (char.IsLetterOrDigit(typedChar) || typedChar == '.'))
            {
                if (m_session == null || m_session.IsDismissed)   // If there is no active session, bring up completion
                {
                    if (TriggerCompletion( ))
                    {
                        if (m_session != null)
                        {
                            m_session.Filter( );
                        }
                    }
                }
                else // The completion session is already active, so just filter
                {
                    m_session.Filter( );
                }

                handled = true;
            }
            else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE ||   // Redo the filter if there is a deletion
                     commandID == (uint)VSConstants.VSStd2KCmdID.DELETE)
            {
                if (m_session != null && !m_session.IsDismissed)
                {
                    m_session.Filter( );
                }

                handled = true;
            }

            return(handled ? VSConstants.S_OK : retVal);
        }
        public static void ParamInfo(this IOleCommandTarget target)
        {
            var guid = VSConstants.VSStd2K;

            ErrorHandler.ThrowOnFailure(target.Exec(ref guid, (int)VSConstants.VSStd2KCmdID.PARAMINFO, 0, IntPtr.Zero, IntPtr.Zero));
        }
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            if (VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider))
            {
                return(m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
            }
            uint commandID = nCmdID;
            char typedChar = char.MinValue;

            if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
            {
                typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
            }

            VSConstants.VSStd2KCmdID nCmdIDEnum = (VSConstants.VSStd2KCmdID)nCmdID;
            //System.Console.WriteLine("Keyboard command: " + nCmdIDEnum);

            if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN ||
                nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB
                /*|| (char.IsWhiteSpace(typedChar) || char.IsPunctuation(typedChar))*/)//this made auto complete on point or space
            {
                if (m_session != null && !m_session.IsDismissed)
                {
                    if (m_session.SelectedCompletionSet.SelectionStatus.IsSelected)
                    {
                        m_session.Commit();
                        return(VSConstants.S_OK);
                    }
                    else
                    {
                        m_session.Dismiss();
                    }
                }
            }

            ThreadHelper.ThrowIfNotOnUIThread();
            int  retVal  = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
            bool handled = false;

            if (!typedChar.Equals(char.MinValue) && char.IsLetterOrDigit(typedChar) || nCmdIDEnum == VSConstants.VSStd2KCmdID.COMPLETEWORD)
            {
                if (m_session == null || m_session.IsDismissed)
                {
                    TriggerCompletion();
                }
                else
                {
                    m_session.Filter();
                }
                handled = true;
            }
            else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE ||
                     commandID == (uint)VSConstants.VSStd2KCmdID.DELETE)
            {
                if (m_session != null && !m_session.IsDismissed)
                {
                    m_session.Filter();
                }
                handled = true;
            }
            if (handled)
            {
                return(VSConstants.S_OK);
            }
            return(retVal);
        }
    public static int WrapExec(
      IOleCommandTarget receiver,
      IOleCommandTarget implementer,
      ref System.Guid pguidCmdGroup,
      uint nCmdID,
      uint nCmdexecopt,
      System.IntPtr pvaIn,
      System.IntPtr pvaOut) {
        Debug.Assert(receiver != null);

      var commandId = new CommandID(pguidCmdGroup, (int)nCmdID);
      if (LogCommand(commandId)) {
        Logger.LogInfo("WrapExec: => recv={0}, impl={1}, parent={2}",
          receiver,
          GetImplementerString(implementer),
          GetParentTargetString(implementer));
      }

      var hr = (implementer == null)
        ? (int)Constants.OLECMDERR_E_NOTSUPPORTED
        : implementer.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
      // Ensures OleMenuCommandService returns OLECMDERR_E_NOTSUPPORTED.
      if (hr == VSConstants.S_OK && implementer is OleMenuCommandService) {
        // Ensure we return OLECMDERR_E_NOTSUPPORTED instead of S_OK if our
        // command does not support the command id. This is necessary so that
        // the VS Shell chains the Exec call to other IOleCommandTarget
        // implementations.
        var service = (OleMenuCommandService)implementer;
        var command = service.FindCommand(commandId);
        if (command != null) {
          if (!command.Supported) {
            hr = (int)Constants.OLECMDERR_E_NOTSUPPORTED;
          }
        }
      }

      if (LogCommand(commandId)) {
        Logger.LogInfo("WrapExec: <= recv={0}, impl={1}, parent={2}, hr={3}",
          receiver,
          GetImplementerString(implementer),
          GetParentTargetString(implementer),
          HrToString(hr));
      }
      return hr;
    }
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            bool handled = false;
            int  hresult = VSConstants.S_OK;

            // 1. Pre-process
            if (pguidCmdGroup == VSConstants.VSStd2K)
            {
                switch ((VSConstants.VSStd2KCmdID)nCmdID)
                {
                case VSConstants.VSStd2KCmdID.AUTOCOMPLETE:
                case VSConstants.VSStd2KCmdID.COMPLETEWORD:
                    handled = StartAutoCompleteSession();
                    break;

                case VSConstants.VSStd2KCmdID.RETURN:
                    handled = CommitAutoComplete(false);
                    break;

                case VSConstants.VSStd2KCmdID.TAB:
                    handled = CommitAutoComplete(true);
                    break;

                case VSConstants.VSStd2KCmdID.CANCEL:
                    handled = CancelAutoComplete();
                    break;
                }
            }

            if (!handled)
            {
                hresult = Next.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
            }

            if (ErrorHandler.Succeeded(hresult))
            {
                if (pguidCmdGroup == VSConstants.VSStd2K)
                {
                    switch ((VSConstants.VSStd2KCmdID)nCmdID)
                    {
                    case VSConstants.VSStd2KCmdID.TYPECHAR:
                        var ch = GetTypeChar(pvaIn);
                        if (ch == ' ')
                        {
                            StartAutoCompleteSession();
                        }
                        else
                        {
                            FilterAutoComplete();
                        }
                        break;

                    case VSConstants.VSStd2KCmdID.BACKSPACE:
                        FilterAutoComplete();
                        break;
                    }
                }
            }

            return(hresult);
        }