演练:获取列出已安装的代码段 (托管包结构)

代码段是可插入到源缓冲区或与菜单命令 (允许选择在安装的代码段中列出) 代码的部分或通过选择代码段快捷方式从 IntelliSense 完成列表。

EnumerateExpansions 方法获取特定语言的 GUID 的所有代码段。 这些代码段的快捷方式插入 IntelliSense 完成列表。

请参见 为代码段 (托管包结构) 支持 有关实现代码段的详细信息在托管包 framework (MPF) 语言服务中。

检索代码段列表

  • 下面的代码演示如何获取代码段列表特定语言的。 结果在字符数组中存储 VsExpansion 结构。 此方法使用静态 GetGlobalService 方法获取 SVsTextManager 服务的 IVsTextManager 接口。 但是,也可以使用服务提供程序为 VSPackage 和调用 QueryService 方法。

    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]);
                            }
                        }
                    }
                }
            }
        }
    }
    

调用 GetSnippets 方法

  • 以下方法演示如何调用 GetSnippets 方法在分析操作完成。 OnParseComplete 方法在开始使用这个原因 Check的分析操作后调用。

备注

出于性能原因缓存的 expansionsList 数组 listis。对代码段的更改未反映在列表中,直到语言服务停止并重新加载 (例如,通过停止并重新启动 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);
        }
    }
}

使用代码段信息

  • 下面的代码演示如何使用 GetSnippets 方法返回的代码段信息。 AddSnippets 方法从该分析器调用以响应任何分析填充代码段列表的原因。 ,在完全分析第一次后,执行发生这种情况。

    AddDeclaration 方法生成完成后显示列出一些列表。

    TestDeclaration 类包含在完成可以显示列表以及声明中的类型的所有信息。

    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"));
                }
            }
        }
    }
    

请参见

概念

为代码段 (托管包结构) 支持