public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { if (pguidCmdGroup == VSConstants.VSStd2K) { if (nCmdID == (uint)VSConstants.VSStd2KCmdID.INSERTSNIPPET || nCmdID == (uint)VSConstants.VSStd2KCmdID.SURROUNDWITH) { IVsTextManager2 textManager = (IVsTextManager2)this.serviceProvider.GetService(typeof(SVsTextManager)); IVsExpansionManager expansionManager; if (VSConstants.S_OK == textManager.GetExpansionManager(out expansionManager)) { expansionManager.InvokeInsertionUI( vsTextView, this, GuidList.guidSpringLanguage, new string[] { "Expansion" }, 1, 0, null, 0, 1, "Insert Snippet", string.Empty); } return VSConstants.S_OK; } if (this.expansionSession != null) { // Handle VS Expansion (Code Snippets) keys if ((nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB)) { if (expansionSession.GoToNextExpansionField(0) == VSConstants.S_OK) return VSConstants.S_OK; } else if ((nCmdID == (uint)VSConstants.VSStd2KCmdID.BACKTAB)) { if (expansionSession.GoToPreviousExpansionField() == VSConstants.S_OK) return VSConstants.S_OK; } else if ((nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.CANCEL)) { if (expansionSession.EndCurrentExpansion(0) == VSConstants.S_OK) { expansionSession = null; return VSConstants.S_OK; } } } // Handle Edit.ListMembers or Edit.CompleteWord commands if ((nCmdID == (uint)VSConstants.VSStd2KCmdID.SHOWMEMBERLIST || nCmdID == (uint)VSConstants.VSStd2KCmdID.COMPLETEWORD)) { if (completionSession != null) { completionSession.Dismiss(); } ShowCompletion(); return VSConstants.S_OK; } // Handle Enter/Tab commit keys if (completionSession != null && (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB)) { if (completionSession.SelectedCompletionSet.SelectionStatus.IsSelected) { completionSession.Commit(); } else { completionSession.Dismiss(); } return VSConstants.S_OK; } // Handle Code Snippets after pressing the Tab key without completion if (completionSession == null && (nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB)) { IVsTextManager2 expansionManager = (IVsTextManager2)this.serviceProvider.GetService(typeof(SVsTextManager)); SnippetsEnumerable snippetsEnumerator = new SnippetsEnumerable(expansionManager, GuidList.guidSpringLanguage); SnapshotPoint currentPoint = (this.textView.Caret.Position.BufferPosition) - 1; ITextStructureNavigator navigator = this.textStructureNavigatorSelectorService.GetTextStructureNavigator(this.textView.TextBuffer); TextExtent extent = navigator.GetExtentOfWord(currentPoint); string shortcut = this.textView.TextSnapshot.GetText(extent.Span); // Search a snippet that matched the token text VsExpansion expansion = snippetsEnumerator.FirstOrDefault(e => e.title == shortcut); if (expansion.title != null) { // Set the location where the snippet will be inserted int startLine, startColumn, endLine, endColumn; this.vsTextView.GetCaretPos(out startLine, out endColumn); startColumn = endColumn - expansion.title.Length; endLine = startLine; // Insert the snippet InsertCodeExpansion(expansion, startLine, startColumn, endLine, endColumn); return VSConstants.S_OK; } } // Hanlde other keys if ((nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)) { char typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); if (completionSession == null) { // Handle trigger keys // Check if the typed char is a trigger if (IsTriggerKey(typedChar)) { var result = this.nextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); ShowCompletion(); return result; } } else { // Handle commit keys // Check if the typed char is a commit key if (IsCommitKey(typedChar)) { SpringCompletion selectedCompletion = completionSession.SelectedCompletionSet.SelectionStatus.Completion as SpringCompletion; if (completionSession.SelectedCompletionSet.SelectionStatus.IsSelected && selectedCompletion != null && selectedCompletion.Type != null && selectedCompletion.Type.Value == SpringCompletionType.Namespace) { completionSession.Commit(); } else { completionSession.Dismiss(); } var result = this.nextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); // Check we should trigger completion after comitting the previous session (for example, after typing dot '.') if (IsTriggerKey(typedChar)) { ShowCompletion(); } return result; } else { var result = this.nextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); completionSession.Filter(); return result; } } } // redo the filter if there is a deletion if (nCmdID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || nCmdID == (uint)VSConstants.VSStd2KCmdID.DELETE) { var result = this.nextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); if (completionSession != null && !completionSession.IsDismissed) { completionSession.Filter(); } return result; } } // we haven't handled this command so pass it onto the next target return this.nextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); }
private IEnumerable<SpringCompletion> GetSnippetsCompletions() { List<SpringCompletion> completions = new List<SpringCompletion>(); IVsTextManager2 expansionManager = (IVsTextManager2)this.serviceProvider.GetService(typeof(SVsTextManager)); SnippetsEnumerable snippetsEnumerator = new SnippetsEnumerable(expansionManager, GuidList.guidSpringLanguage); completions.AddRange(snippetsEnumerator.Select(vsExpansion => new SpringCompletion(this.glyphService, vsExpansion))); completions.Sort(); return completions; }