Walkthrough: Getting a List of Installed Code Snippets (Managed Package Framework)
A code snippet is a piece of code that can be inserted into the source buffer either with a menu command (which allows choosing among a list of installed code snippets) or by selecting a snippet shortcut from an IntelliSense completion list.
The EnumerateExpansions method gets all code snippets for a specific language GUID. The shortcuts for those snippets can be inserted into an IntelliSense completion list.
See Support for Code Snippets (Managed Package Framework) for details about implementing code snippets in a managed package framework (MPF) language service.
To retrieve a list of code snippets
The following code shows how to get a list of code snippets for a given language. The results are stored in an array of VsExpansion structures. This method uses the static GetGlobalService method to get the IVsTextManager interface from the SVsTextManager service. However, you can also use the service provider given to your VSPackage and call the QueryService method.
using System; using System.Collections; using System.Runtime.InteropServices; using Microsoft.VisualStudio.Package; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.TextManager.Interop; [Guid("00000000-0000-0000-0000-000000000000")] //create a new GUID for the language service namespace TestLanguage { class TestLanguageService : LanguageService { private void GetSnippets(Guid languageGuid, ref ArrayList expansionsList) { IVsTextManager textManager = (IVsTextManager)Package.GetGlobalService(typeof(SVsTextManager)); if (textManager != null) { IVsTextManager2 textManager2 = (IVsTextManager2)textManager; if (textManager2 != null) { IVsExpansionManager expansionManager = null; textManager2.GetExpansionManager(out expansionManager); if (expansionManager != null) { // Tell the environment to fetch all of our snippets. IVsExpansionEnumeration expansionEnumerator = null; expansionManager.EnumerateExpansions(languageGuid, 0, // return all info null, // return all types 0, // return all types 1, // include snippets without types 0, // do not include duplicates out expansionEnumerator); if (expansionEnumerator != null) { // Cache our expansions in a VsExpansion array uint count = 0; uint fetched = 0; VsExpansion expansionInfo = new VsExpansion(); IntPtr[] pExpansionInfo = new IntPtr[1]; // Allocate enough memory for one VSExpansion structure. This memory is filled in by the Next method. pExpansionInfo[0] = Marshal.AllocCoTaskMem(Marshal.SizeOf(expansionInfo)); expansionEnumerator.GetCount(out count); for (uint i = 0; i < count; i++) { expansionEnumerator.Next(1, pExpansionInfo, out fetched); if (fetched > 0) { // Convert the returned blob of data into a structure that can be read in managed code. expansionInfo = (VsExpansion)Marshal.PtrToStructure(pExpansionInfo[0], typeof(VsExpansion)); if (!String.IsNullOrEmpty(expansionInfo.shortcut)) { expansionsList.Add(expansionInfo); } } } Marshal.FreeCoTaskMem(pExpansionInfo[0]); } } } } } } }
To call the GetSnippets method
- The following method shows how to call the GetSnippets method at the completion of a parsing operation. The OnParseComplete method is called after a parsing operation that was started with the reason Check.
备注
The expansionsList array listis cached for performance reasons. Changes to the snippets are not reflected in the list until the language service is stopped and reloaded (for example, by stopping and restarting Visual Studio).
class TestLanguageService : LanguageService
{
private ArrayList expansionsList;
public override void OnParseComplete(ParseRequest req)
{
if (this.expansionsList == null)
{
this.expansionsList = new ArrayList();
GetSnippets(this.GetLanguageServiceGuid(),
ref this.expansionsList);
}
}
}
To use the snippet information
The following code shows how to use the snippet information returned by the GetSnippets method. The AddSnippets method is called from the parser in response to any parse reason that is used to populate a list of code snippets. This should take place after the full parse has been done for the first time.
The AddDeclaration method builds a list of declarations that is later displayed in a completion list.
The TestDeclaration class contains all the information that can be displayed in a completion list as well as the type of declaration.
class TestAuthoringScope : AuthoringScope { public void AddDeclarations(TestDeclaration declaration) { if (m_declarations == null) m_declarations = new List<TestDeclaration>(); m_declarations.Add(declaration); } } class TestDeclaration { private string m_name; private string m_description; private string m_type; public TestDeclaration(string name, string desc, string type) { m_name = name; m_description = desc; m_type = type; } class TestLanguageService : LanguageService { internal void AddSnippets(ref TestAuthoringScope scope) { if (this.expansionsList != null && this.expansionsList.Count > 0) { int count = this.expansionsList.Count; for (int i = 0; i < count; i++) { VsExpansion expansionInfo = (VsExpansion)this.expansionsList[i]; scope.AddDeclaration(new TestDeclaration(expansionInfo.title, expansionInfo.description, "snippet")); } } } }