public int InvokeInsertionUI(int invokationCommand) { if ((_expansionManager != null) && (TextView != null)) { // Set the allowable snippet types and prompt text according to the current command. string[] snippetTypes = null; var promptText = ""; if (invokationCommand == (uint)VSConstants.VSStd2KCmdID.INSERTSNIPPET) { snippetTypes = AllStandardSnippetTypes; promptText = Resources.InsertSnippet; } else if (invokationCommand == (uint)VSConstants.VSStd2KCmdID.SURROUNDWITH) { snippetTypes = SurroundWithSnippetTypes; promptText = Resources.SurrondWithSnippet; } return(_expansionManager.InvokeInsertionUI( TextView.GetViewAdapter <IVsTextView>(), this, RGuidList.RLanguageServiceGuid, snippetTypes, snippetTypes?.Length ?? 0, 0, null, // Snippet kinds 0, // Length of snippet kinds 0, promptText, "\t")); } return(VSConstants.E_UNEXPECTED); }
private void TriggerSnippet(uint nCmdID) { if (_expansionMgr != null) { string prompt; string[] snippetTypes; if ((VSConstants.VSStd2KCmdID)nCmdID == VSConstants.VSStd2KCmdID.SURROUNDWITH) { prompt = SR.GetString(SR.SurroundWith); snippetTypes = _surroundsWithSnippetTypes; } else { prompt = SR.GetString(SR.InsertSnippet); snippetTypes = _allStandardSnippetTypes; } _expansionMgr.InvokeInsertionUI( GetViewAdapter(), _expansionClient, GuidList.guidPythonLanguageServiceGuid, snippetTypes, snippetTypes.Length, 0, null, 0, 0, prompt, ">" ); } }
public override int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { //the snippet picker code starts here if (nCmdID == (uint)VSConstants.VSStd2KCmdID.INSERTSNIPPET) { _manager.InvokeInsertionUI( _vsTextView, this, //the expansion client new Guid(_guid), null, //use all snippet types 0, //number of types (0 for all) 0, //ignored if iCountTypes == 0 null, //use all snippet kinds 0, //use all snippet kinds 0, //ignored if iCountTypes == 0 Constants.LanguageName, //the text to show in the prompt string.Empty); //only the ENTER key causes insert return(VSConstants.S_OK); } if (_session != null) { if (nCmdID == (uint)VSConstants.VSStd2KCmdID.BACKTAB) { _session.GoToPreviousExpansionField(); return(VSConstants.S_OK); } else if (nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB) { _session.GoToNextExpansionField(0); //false to support cycling through all the fields return(VSConstants.S_OK); } else if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.CANCEL) { if (_session.EndCurrentExpansion(0) == VSConstants.S_OK) { _session = null; return(VSConstants.S_OK); } } } if (_session == null && nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB) { CaretPosition pos = _view.Caret.Position; TextExtent word = _navigator.GetTextStructureNavigator(_view.TextBuffer).GetExtentOfWord(pos.BufferPosition - 1); string textString = word.Span.GetText(); if (InsertAnyExpansion(textString, null, null)) { EndSession(); return(VSConstants.S_OK); } } ThreadHelper.ThrowIfNotOnUIThread(); return(Next.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); }
public void ExpansionClientTest() { var textBuffer = new TextBufferMock("if", RContentTypeDefinition.ContentType); var textView = new TextViewMock(textBuffer); var client = new ExpansionClient(textView, textBuffer, _expansionManager, _cache, _services); client.IsEditingExpansion().Should().BeFalse(); client.IsCaretInsideSnippetFields().Should().BeFalse(); _expansionManager.InvokeInsertionUI(null, null, Guid.Empty, new string[0], 0, 0, new string[0], 0, 0, string.Empty, string.Empty) .ReturnsForAnyArgs(VSConstants.S_OK); client.InvokeInsertionUI((int)VSConstants.VSStd2KCmdID.INSERTSNIPPET).Should().Be(VSConstants.S_OK); textView.Caret.MoveTo(new SnapshotPoint(textView.TextBuffer.CurrentSnapshot, 2)); bool inserted; client.StartSnippetInsertion(out inserted); inserted.Should().BeTrue(); client.IsEditingExpansion().Should().BeTrue(); client.EndExpansion(); client.IsEditingExpansion().Should().BeFalse(); client.OnItemChosen("if", "path"); client.IsEditingExpansion().Should().BeTrue(); client.EndExpansion(); client.IsEditingExpansion().Should().BeFalse(); client.IsCaretInsideSnippetFields().Should().BeFalse(); }
private void TriggerSnippet(uint nCmdID) { if (_mExManager == null) { return; } string prompt; string[] snippetTypes; if ((VSConstants.VSStd2KCmdID)nCmdID == VSConstants.VSStd2KCmdID.SURROUNDWITH) { prompt = "Surround with:"; snippetTypes = _surroundsWithSnippetTypes; } else { prompt = "Insert snippet:"; snippetTypes = _allStandardSnippetTypes; } _mExManager.InvokeInsertionUI( _view, this, new Guid(GuidList.PowerShellLanguage), snippetTypes, snippetTypes.Length, 0, null, 0, 0, prompt, ">" ); }
public bool ShowInsertionUI(ITextView textView, bool isSurroundsWith) { if (textView == null) { throw new ArgumentNullException(nameof(textView)); } if (_vsExpansionMgr == null) { return(false); } string prompt; string[] snippetTypes; if (isSurroundsWith) { prompt = Strings.SurroundWith; snippetTypes = _surroundsWithSnippetTypes; } else { prompt = Strings.InsertSnippet; snippetTypes = _allStandardSnippetTypes; } var client = GetOrCreateExpansionClient(textView); var hr = _vsExpansionMgr.InvokeInsertionUI( _editorAdaptersFactoryService.GetViewAdapter(textView), client, CommonGuidList.guidPythonLanguageServiceGuid, snippetTypes, snippetTypes.Length, 0, null, 0, 0, prompt, ">" ); return(ErrorHandler.Succeeded(hr)); }
/// <summary> /// Executes a specified command or displays help for a command. /// </summary> /// <param name="pguidCmdGroupRef">Pointer to unique identifier of the command group; can be NULL to specify the standard group.</param> /// <param name="nCmdID">The command to be executed. This command must belong to the group specified with pguidCmdGroup.</param> /// <param name="nCmdexecopt">Values taken from the OLECMDEXECOPT enumeration, which describe how the object should execute the command.</param> /// <param name="pvaIn">Pointer to a VARIANTARG structure containing input arguments. Can be NULL.</param> /// <param name="pvaOut">Pointer to a VARIANTARG structure to receive command output. Can be NULL.</param> /// <returns>This method supports the standard return values E_FAIL and E_UNEXPECTED, as well as the following: /// S_OK /// The command was executed successfully. /// OLECMDERR_E_UNKNOWNGROUP /// The pguidCmdGroup parameter is not NULL but does not specify a recognized command group. /// OLECMDERR_E_NOTSUPPORTED /// The nCmdID parameter is not a valid command in the group identified by pguidCmdGroup. /// OLECMDERR_E_DISABLED /// The command identified by nCmdID is currently disabled and cannot be executed. /// OLECMDERR_E_NOHELP /// The caller has asked for help on the command identified by nCmdID, but no help is available. /// OLECMDERR_E_CANCELED /// The user canceled the execution of the command.</returns> public int Exec(ref Guid pguidCmdGroupRef, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { //the snippet picker code starts here if (nCmdID == (uint)VSConstants.VSStd2KCmdID.INSERTSNIPPET) { IVsTextManager2 textManager = (IVsTextManager2)languageService.GetService(typeof(SVsTextManager)); textManager.GetExpansionManager(out m_exManager); IVsExpansionEnumeration expansionEnumerator = null; int ret = m_exManager.EnumerateExpansions(Guids.LuaLanguageService, 0, // return all info null, // return all types 0, // return all types 1, // include snippets without types 0, // do not include duplicates out expansionEnumerator); uint count = 0; if (expansionEnumerator != null) { expansionEnumerator.GetCount(out count); } if (count == 0) { RegisterCodeSnippets(); return(VSConstants.S_OK); } m_exManager.InvokeInsertionUI( m_vsTextView, this, //the expansion client Guids.LuaLanguageService, null, //use all snippet types 0, //number of types (0 for all) 0, //ignored if iCountTypes == 0 null, //use all snippet kinds 0, //use all snippet kinds 0, //ignored if iCountTypes == 0 "Lua", //the text to show in the prompt string.Empty); //only the ENTER key causes insert return(VSConstants.S_OK); } //the expansion insertion is handled in OnItemChosen //if the expansion session is still active, handle tab/backtab/return/cancel if (m_exSession != null) { if (nCmdID == (uint)VSConstants.VSStd2KCmdID.BACKTAB) { m_exSession.GoToPreviousExpansionField(); return(VSConstants.S_OK); } else if (nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB) { m_exSession.GoToNextExpansionField(0); //false to support cycling through all the fields return(VSConstants.S_OK); } else if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.CANCEL) { if (m_exSession.EndCurrentExpansion(0) == VSConstants.S_OK) { m_exSession = null; return(VSConstants.S_OK); } } } //neither an expansion session nor a completion session is open, but we got a tab, so check whether the last word typed is a snippet shortcut //if (m_exSession == null && nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB) //{ // //get the word that was just added // CaretPosition pos = m_vsTextView.Caret.Position; // TextExtent word = languageService.NavigatorService.GetTextStructureNavigator(m_textView.TextBuffer).GetExtentOfWord(pos.BufferPosition - 1); //use the position 1 space back // string textString = word.Span.GetText(); //the word that was just added // //if it is a code snippet, insert it, otherwise carry on // if (InsertAnyExpansion(textString, null, null)) // return VSConstants.S_OK; //} #if SUPPORT_REFACTOR string commandId = VSIDECommands.GetCommandId(pguidCmdGroupRef, nCmdID); if (!string.IsNullOrEmpty(commandId)) { // refactor and undo are not working anyway. { //Refactor command if (VSIDECommands.IsRightClick(pguidCmdGroupRef, nCmdID)) { SetRefactorMenuBars(); return(ExecVsHandler(ref pguidCmdGroupRef, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } //Undo command if (commandId == "cmdidUndo") { var luaUndoService = languageService.GetService(typeof(ILuaUndoService)) as ILuaUndoService; if (luaUndoService != null) { luaUndoService.Undo(); } return(ExecVsHandler(ref pguidCmdGroupRef, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } } } #endif return(ExecVsHandler(ref pguidCmdGroupRef, nCmdID, nCmdexecopt, pvaIn, pvaOut)); }
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); * } */ // Show the snippet picker if (nCmdID == (uint)VSConstants.VSStd2KCmdID.INSERTSNIPPET) { expansionManager.InvokeInsertionUI( vsTextView, this, //the expansion client Helpers.Constants.LanguageGuid, null, //use all snippet types 0, //number of types (0 for all) 0, //ignored if iCountTypes == 0 null, //use all snippet kinds 0, //use all snippet kinds 0, //ignored if iCountTypes == 0 "Cake Snippets", //the text to show in the prompt string.Empty); //only the ENTER key causes insert return(VSConstants.S_OK); } //the expansion insertion is handled in OnItemChosen //if the expansion session is still active, handle tab/back-tab/return/cancel if (session != null) { if (nCmdID == (uint)VSConstants.VSStd2KCmdID.BACKTAB) { session.GoToPreviousExpansionField(); return(VSConstants.S_OK); } else if (nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB) { session.GoToNextExpansionField(0); //false to support cycling through all the fields return(VSConstants.S_OK); } else if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.CANCEL) { if (session.EndCurrentExpansion(0) == VSConstants.S_OK) { session = null; return(VSConstants.S_OK); } } } //neither an expansion session nor a completion session is open, but we got a tab, so check whether the last word typed is a snippet shortcut if (session == null && nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB) { //get the word that was just added CaretPosition pos = textView.Caret.Position; TextExtent word = provider.NavigatorService.GetTextStructureNavigator(textView.TextBuffer).GetExtentOfWord(pos.BufferPosition - 1); //use the position 1 space back string textString = word.Span.GetText(); //the word that was just added //if it is a code snippet, insert it, otherwise carry on if (InsertAnyExpansion(textString, null, null)) { EndSession(); return(VSConstants.S_OK); } } return(nextCommandHandler.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); } //the snippet picker code starts here if (nCmdID == (uint)VSConstants.VSStd2KCmdID.INSERTSNIPPET) { IVsTextManager2 textManager = (IVsTextManager2)_provider._serviceProvider.GetService(typeof(SVsTextManager)); textManager.GetExpansionManager(out _exManager); _exManager.InvokeInsertionUI( _vsTextView, this, //the expansion client new Guid(GuidList.guidDaxLanguageService), null, //use all snippet types 0, //number of types (0 for all) 0, //ignored if iCountTypes == 0 null, //use all snippet kinds 0, //use all snippet kinds 0, //ignored if iCountTypes == 0 "DAX Snippets", //the text to show in the prompt string.Empty); //only the ENTER key causes insert return(VSConstants.S_OK); } //the expansion insertion is handled in OnItemChosen //if the expansion session is still active, handle tab/backtab/return/cancel if (_exSession != null) { if (nCmdID == (uint)VSConstants.VSStd2KCmdID.BACKTAB) { _exSession.GoToPreviousExpansionField(); return(VSConstants.S_OK); } else if (nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB) { _exSession.GoToNextExpansionField(0); //false to support cycling through all the fields return(VSConstants.S_OK); } else if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.CANCEL) { if (_exSession.EndCurrentExpansion(0) == VSConstants.S_OK) { _exSession = null; return(VSConstants.S_OK); } } } //neither an expansion session nor a completion session is open, but we got a tab, so check whether the last word typed is a snippet shortcut if (/*m_session == null && */ _exSession == null && nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB) { //get the word that was just added CaretPosition pos = _textView.Caret.Position; TextExtent word = _provider._navigatorService.GetTextStructureNavigator(_textView.TextBuffer).GetExtentOfWord(pos.BufferPosition - 1); //use the position 1 space back string textString = word.Span.GetText(); //the word that was just added //if it is a code snippet, insert it, otherwise carry on if (InsertAnyExpansion(textString, null, null)) { return(VSConstants.S_OK); } } // 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) { _session.Commit(); // Also, don't add the character to the buffer return(VSConstants.S_OK); } 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 = _nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); bool handled = false; if (!typedChar.Equals(char.MinValue) && char.IsLetterOrDigit(typedChar)) { if (_session == null || _session.IsDismissed) // If there is no active session, bring up completion { this.TriggerCompletion(); _session.Filter(); } else // The completion session is already active, so just filter { _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(); } handled = true; } if (handled) { return(VSConstants.S_OK); } return(retVal); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { ThreadHelper.ThrowIfNotOnUIThread(); char typedChar = '\0'; if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR) { typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); } if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.INSERTSNIPPET) { if (_exManager != null) { int result = _exManager.InvokeInsertionUI(_viewAdapter, this, GuidList.guidSnippets, null, 0, 0, null, 0, 0, "DK Snippets", string.Empty); return(VSConstants.S_OK); } } if (_exSession != null) { if (nCmdID == (uint)VSConstants.VSStd2KCmdID.BACKTAB) { _exSession.GoToPreviousExpansionField(); return(VSConstants.S_OK); } if (nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB) { _exSession.GoToNextExpansionField(0); // 0 to cycle through fields return(VSConstants.S_OK); } if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.CANCEL) { if (_exSession.EndCurrentExpansion(0) == VSConstants.S_OK) { _exSession = null; return(VSConstants.S_OK); } } } else if (_exSession == null && nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB) { var caretPos = _view.Caret.Position.BufferPosition; var prefix = _view.TextSnapshot.GetLineTextUpToPosition(caretPos); var match = _rxWordEnd.Match(prefix); if (match.Success) { var word = match.Groups[1].Value; if (InsertAnyExpansion(word, null, null)) { return(VSConstants.S_OK); } } } return(_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); }