I need to add support for Code Snippets to my Lanuage Service(which I am writing using MPF). I am doing all according to this MSDN article.
First I've added attribute to my package class, like:
[ProvideLanguageCodeExpansion(typeof(MyLanguageService),"My Language",0,"My Language",@"C:\My\SnippetsIndex.xml",// Path to snippets indexSearchPaths=@"C:\My\Snippets\")]// Path to snippetsSnippetsIndex.xml file content is following:
<?xml version="1.0" encoding="utf-8"?><SnippetCollection><LanguageLang="My Language"Guid="{1c9caaac-65b9-40f8-9f39-ab77a824d351}"><SnippetDir><OnOff>On</OnOff><Installed>true</Installed><Locale>%LCID%</Locale><DirPath>C:\My\Snippets\</DirPath><LocalizedName>Snippets</LocalizedName></SnippetDir></Language></SnippetCollection>And in this folder there is one file with default snippet, like:
<?xml version="1.0" encoding="utf-8"?><CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"><CodeSnippetFormat="1.0.0"><Header><SnippetTypes><SnippetType>Expansion</SnippetType></SnippetTypes><Title>SnippetFile1</Title><Author>dd</Author><Description></Description><HelpUrl></HelpUrl><Shortcut></Shortcut></Header><Snippet><CodeLanguage="My Language"Delimiter="$"><![CDATA[TEST TEST]]></Code></Snippet></CodeSnippet></CodeSnippets>I've added method for detecting installed snippets from this article to LanguageService class:
privatevoid_GetSnippets(Guid languageGuid,refArrayList 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 infonull,// return all types0,// return all types1,// include snippets without types0,// do not include duplicatesout expansionEnumerator);if(expansionEnumerator !=null){// Cache our expansions in a VsExpansion array uint count =0;uint fetched =0;VsExpansion expansionInfo =newVsExpansion();IntPtr[] pExpansionInfo =newIntPtr[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]);}}}}}
If I call this method from package initializing method I got count
== 0 in line
expansionEnumerator.GetCount(out count);
And if I call it from method ParseSource in LanguageService class
as MSDN recommends, I've just got expansionEnumerator
== null.
I've spent much time trying to understand whats going on, but still got this strange result. Could anybody tell me what am I doing wrong?