Walkthrough: Getting a List of Installed Code Snippets (Legacy Implementation)
Applies to: Visual Studio Visual Studio for Mac
Note
This article applies to Visual Studio 2017. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here
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 in a Legacy Language Service 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 ParseReason.
Note
The expansionsList
array list is 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. TheAddSnippets
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")); } } } }