İzlenecek yol: Kod parçacıkları uygulama

Kod parçacıkları oluşturabilir ve bir düzenleyici uzantısına ekleyebilirsiniz, böylece uzantı kullanıcıları bunları kendi kodlarına ekleyebilir.

Kod parçacığı, bir dosyaya dahil edilebilen bir kod parçası veya başka bir metindir. Belirli programlama dilleri için kaydedilmiş tüm kod parçacıklarını görüntülemek için, Araçlar menüsünde Kod Parçacığı Yöneticisi'ne tıklayın. Dosyaya kod parçacığı eklemek için, kod parçacığını istediğiniz yere sağ tıklayın, Kod Parçacığı Ekle'ye veya İle Çevrele'ye tıklayın, istediğiniz kod parçacığını bulun ve çift tıklayın. Kod parçacığının ilgili bölümlerini değiştirmek için Sekme veya Shift+Sekme tuşuna basın ve ardından enter veya Esc tuşuna basarak bunu kabul edin. Daha fazla bilgi için bkz . Kod parçacıkları.

.snippet* dosya adı uzantısına sahip bir XML dosyasında bir kod parçacığı bulunur. Kod parçacığı, kod parçacığı eklendikten sonra vurgulanan alanlar içerebilir, böylece kullanıcı bunları bulabilir ve değiştirebilir. Kod parçacığı dosyası, kod parçacığı adını doğru kategoride görüntüleyebilmesi için Kod Parçacığı Yöneticisi için de bilgi sağlar. Kod parçacığı şeması hakkında bilgi için bkz . Kod parçacıkları şema başvurusu.

Bu kılavuzda şu görevlerin nasıl yerine getir edileceği öğretlenmiştir:

  1. Belirli bir dil için kod parçacıkları oluşturun ve kaydedin.

  2. Kod Parçacığı Ekle komutunu bir kısayol menüsüne ekleyin.

  3. Kod parçacığı genişletmesi uygulayın.

    Bu izlenecek yol İzlenecek yol: Görüntü deyimi tamamlamayı temel alır.

Kod parçacıkları oluşturma ve kaydetme

Kod parçacıkları genellikle kayıtlı bir dil hizmetiyle ilişkilendirilir. Ancak, kod parçacıklarını kaydetmek için bir LanguageService uygulamanız gerekmez. Bunun yerine, kod parçacığı dizin dosyasında bir GUID belirtin ve projenize eklediğiniz GUID'nin ProvideLanguageCodeExpansionAttribute aynısını kullanın.

Aşağıdaki adımlarda kod parçacıkları oluşturma ve bunları belirli bir GUID ile ilişkilendirme gösterilmektedir.

  1. Aşağıdaki dizin yapısını oluşturun:

    %InstallDir%\TestSnippets\Snippets\1033\

    burada %InstallDir% Visual Studio yükleme klasörüdür. (Bu yol genellikle kod parçacıkları yüklemek için kullanılır, ancak herhangi bir yol belirtebilirsiniz.)

  2. \1033\ klasöründe bir .xml dosyası oluşturun ve bunu TestSnippets.xml olarak adlandırın. (Bu ad genellikle bir kod parçacığı dizin dosyası için kullanılasa da, .xml dosya adı uzantısına sahip olduğu sürece herhangi bir ad belirtebilirsiniz.) Aşağıdaki metni ekleyin ve ardından yer tutucu GUID'sini silin ve kendi yer tutucunuzu ekleyin.

    <?xml version="1.0" encoding="utf-8" ?>
    <SnippetCollection>
        <Language Lang="TestSnippets" Guid="{00000000-0000-0000-0000-000000000000}">
            <SnippetDir>
                <OnOff>On</OnOff>
                <Installed>true</Installed>
                <Locale>1033</Locale>
                <DirPath>%InstallRoot%\TestSnippets\Snippets\%LCID%\</DirPath>
                <LocalizedName>Snippets</LocalizedName>
            </SnippetDir>
        </Language>
    </SnippetCollection>
    
  3. Kod parçacığı klasöründe bir dosya oluşturun, test.snippet olarak adlandırın ve aşağıdaki metni ekleyin:

    <?xml version="1.0" encoding="utf-8" ?>
    <CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
        <CodeSnippet Format="1.0.0">
            <Header>
                <Title>Test replacement fields</Title>
                <Shortcut>test</Shortcut>
                <Description>Code snippet for testing replacement fields</Description>
                <Author>MSIT</Author>
                <SnippetTypes>
                    <SnippetType>Expansion</SnippetType>
                </SnippetTypes>
            </Header>
            <Snippet>
                <Declarations>
                    <Literal>
                      <ID>param1</ID>
                        <ToolTip>First field</ToolTip>
                        <Default>first</Default>
                    </Literal>
                    <Literal>
                        <ID>param2</ID>
                        <ToolTip>Second field</ToolTip>
                        <Default>second</Default>
                    </Literal>
                </Declarations>
                <References>
                   <Reference>
                       <Assembly>System.Windows.Forms.dll</Assembly>
                   </Reference>
                </References>
                <Code Language="TestSnippets">
                    <![CDATA[MessageBox.Show("$param1$");
         MessageBox.Show("$param2$");]]>
                </Code>
            </Snippet>
        </CodeSnippet>
    </CodeSnippets>
    

    Aşağıdaki adımlarda kod parçacıklarının nasıl kaydedileceğini gösterilmektedir.

Belirli bir GUID için kod parçacıklarını kaydetmek için

  1. CompletionTest projesini açın. Bu projenin nasıl oluşturulacağı hakkında bilgi için bkz . İzlenecek yol: Deyim tamamlamasını görüntüleme.

  2. Projede, aşağıdaki derlemelere başvurular ekleyin:

    • Microsoft.VisualStudio.TextManager.Interop

    • Microsoft.VisualStudio.TextManager.Interop.8.0

    • microsoft.msxml

  3. Projede source.extension.vsixmanifest dosyasını açın.

  4. Varlıklar sekmesinin bir VsPackage içerik türü içerdiğinden ve Project'in projenin adına ayarlandığından emin olun.

  5. CompletionTest projesini seçin ve Özellikler penceresi Pkgdef Dosyası Oluştur seçeneğini true olarak ayarlayın. Projeyi kaydedin.

  6. Projeye statik SnippetUtilities bir sınıf ekleyin.

    static class SnippetUtilities
    
  7. SnippetUtilities sınıfında bir GUID tanımlayın ve SnippetsIndex.xml dosyasında kullandığınız değeri verin.

    internal const string LanguageServiceGuidStr = "00000000-0000-0000-0000-00000000";
    
  8. ProvideLanguageCodeExpansionAttribute sınıfına TestCompletionHandler ekleyin. Bu öznitelik, projedeki herhangi bir genel veya iç (statik olmayan) sınıfa eklenebilir. (Microsoft.VisualStudio.Shell ad alanı için bir using yönerge eklemeniz gerekebilir.)

    [ProvideLanguageCodeExpansion(
    SnippetUtilities.LanguageServiceGuidStr,
    "TestSnippets", //the language name
    0,              //the resource id of the language
    "TestSnippets", //the language ID used in the .snippet files
    @"%InstallRoot%\TestSnippets\Snippets\%LCID%\TestSnippets.xml",
        //the path of the index file
    SearchPaths = @"%InstallRoot%\TestSnippets\Snippets\%LCID%\",
    ForceCreateDirs = @"%InstallRoot%\TestSnippets\Snippets\%LCID%\")]
    internal class TestCompletionCommandHandler : IOleCommandTarget
    
  9. Projeyi derleyin ve çalıştırın. Proje çalıştırıldığında başlayan deneysel Visual Studio örneğinde, az önce kaydettiğiniz kod parçacığı Kod Parçacıkları Yöneticisi'nde TestSnippets dili altında görüntülenmelidir.

Kısayol menüsüne Kod Parçacığı Ekle komutunu ekleyin

Kod Parçacığı Ekle komutu, metin dosyasının kısayol menüsüne eklenmez. Bu nedenle komutunu etkinleştirmeniz gerekir.

Kod Parçacığı Ekle komutunu kısayol menüsüne eklemek için

  1. TestCompletionCommandHandler Sınıf dosyasını açın.

    Bu sınıf uyguladığındanIOleCommandTarget, yönteminde QueryStatus Kod Parçacığı Ekle komutunu etkinleştirebilirsiniz. Komutu etkinleştirmeden önce, Kod Parçacığı Ekle komutuna tıklandığında kod parçacığı seçici kullanıcı arabirimini (UI) görüntülediğinden, bu yöntemin otomasyon işlevi içinde çağrılmadığını denetleyin.

    public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
    {
        if (!VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider))
        {
            if (pguidCmdGroup == VSConstants.VSStd2K && cCmds > 0)
            {
                // make the Insert Snippet command appear on the context menu 
                if ((uint)prgCmds[0].cmdID == (uint)VSConstants.VSStd2KCmdID.INSERTSNIPPET)
                {
                    prgCmds[0].cmdf = (int)Constants.MSOCMDF_ENABLED | (int)Constants.MSOCMDF_SUPPORTED;
                    return VSConstants.S_OK;
                }
            }
        }
    
        return m_nextCommandHandler.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
    }
    
  2. Projeyi derleyin ve çalıştırın. Deneysel örnekte,.zzz dosya adı uzantısına sahip bir dosyayı açın ve içinde herhangi bir yere sağ tıklayın. Kod Parçacığı Ekle komutu kısayol menüsünde görünmelidir.

Kod Parçacığı Seçici kullanıcı arabiriminde kod parçacığı genişletmesi uygulama

Bu bölümde, kısayol menüsünde Kod Parçacığı Ekle'ye tıklandığında kod parçacığı seçici kullanıcı arabiriminin görüntülenmesi için kod parçacığı genişletmesinin nasıl uygulandığını gösterir. Bir kullanıcı kod parçacığı kısayolunu yazdığında ve ardından Sekme tuşuna bastığında kod parçacığı da genişletilir.

Kod parçacığı seçici kullanıcı arabirimini görüntülemek ve gezintiyi ve ekleme sonrası kod parçacığı kabulü Exec etkinleştirmek için yöntemini kullanın. Ekleme yöntemi tarafından OnItemChosen işlenir.

Kod parçacığı genişletmesinin uygulanması eski Microsoft.VisualStudio.TextManager.Interop arabirimleri kullanır. Geçerli düzenleyici sınıflarından eski koda çeviri yaptığınızda, eski arabirimlerin metin arabelleğindeki konumları belirtmek için satır numaraları ve sütun numaralarının bir bileşimini kullandığını, ancak geçerli sınıfların tek bir dizin kullandığını unutmayın. Bu nedenle, arabellekte her biri 10 karakterden oluşan üç satır varsa (artı bir karakter olarak sayılan yeni bir satır), üçüncü satırdaki dördüncü karakter geçerli uygulamada 27 konumundadır, ancak 2. satırdadır, eski uygulamada 3. konumdadır.

Kod parçacığı genişletmesini uygulamak için

  1. sınıfını içeren dosyaya TestCompletionCommandHandler aşağıdaki using yönergeleri ekleyin.

    using Microsoft.VisualStudio.Text.Operations;
    using MSXML;
    using System.ComponentModel.Composition;
    
  2. TestCompletionCommandHandler sınıfının arabirimini IVsExpansionClient uygulamasını sağlayın.

    internal class TestCompletionCommandHandler : IOleCommandTarget, IVsExpansionClient
    
  3. TestCompletionCommandHandlerProvider sınıfında, öğesini içeri aktarınITextStructureNavigatorSelectorService.

    [Import]
    internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
    
  4. Kod genişletme arabirimleri ve IVsTextViewiçin bazı özel alanlar ekleyin.

    IVsTextView m_vsTextView;
    IVsExpansionManager m_exManager;
    IVsExpansionSession m_exSession;
    
  5. sınıfının oluşturucusunda TestCompletionCommandHandler aşağıdaki alanları ayarlayın.

    internal TestCompletionCommandHandler(IVsTextView textViewAdapter, ITextView textView, TestCompletionHandlerProvider provider)
    {
        this.m_textView = textView;
        m_vsTextView = textViewAdapter;
        m_provider = provider;
        //get the text manager from the service provider
        IVsTextManager2 textManager = (IVsTextManager2)m_provider.ServiceProvider.GetService(typeof(SVsTextManager));
        textManager.GetExpansionManager(out m_exManager);
        m_exSession = null;
    
        //add the command to the command chain
        textViewAdapter.AddCommandFilter(this, out m_nextCommandHandler);
    }
    
  6. Kullanıcı Kod Parçacığı Ekle komutuna tıkladığında kod parçacığı seçicisini görüntülemek için yöntemine Exec aşağıdaki kodu ekleyin. (Bu açıklamayı Exec()daha okunabilir hale getirmek için deyim tamamlama için kullanılan kod gösterilmez; bunun yerine kod blokları mevcut yönteme eklenir.) Bir karakteri denetleen kodun arkasına aşağıdaki kod bloğunu ekleyin.

    //code previously written for Exec
    if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
    {
        typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
    }
    //the snippet picker code starts here
    if (nCmdID == (uint)VSConstants.VSStd2KCmdID.INSERTSNIPPET)
    {
        IVsTextManager2 textManager = (IVsTextManager2)m_provider.ServiceProvider.GetService(typeof(SVsTextManager));
    
        textManager.GetExpansionManager(out m_exManager);
    
        m_exManager.InvokeInsertionUI(
            m_vsTextView,
            this,      //the expansion client
            new Guid(SnippetUtilities.LanguageServiceGuidStr),
            null,       //use all snippet types
            0,          //number of types (0 for all)
            0,          //ignored if iCountTypes == 0
            null,       //use all snippet kinds
            0,          //use all snippet kinds
            0,          //ignored if iCountTypes == 0
            "TestSnippets", //the text to show in the prompt
            string.Empty);  //only the ENTER key causes insert 
    
        return VSConstants.S_OK;
    }
    
  7. Kod parçacığında gezinilebilen alanlar varsa genişletme oturumu açıkça kabul edilene kadar açık tutulur; kod parçacığında alan yoksa oturum kapatılır ve yöntemi tarafından InvokeInsertionUI olarak null döndürülür. yöntemindeExec, önceki adımda eklediğiniz kod parçacığı seçici kullanıcı arabirimi kodundan sonra kod parçacığı gezintisini işlemek için aşağıdaki kodu ekleyin (kullanıcı kod parçacığı eklendikten sonra Sekme veya Shift+Sekmesi'ne bastığında).

    //the expansion insertion is handled in OnItemChosen
    //if the expansion session is still active, handle tab/backtab/return/cancel
    if (m_exSession != null)
    {
        if (nCmdID == (uint)VSConstants.VSStd2KCmdID.BACKTAB)
        {
            m_exSession.GoToPreviousExpansionField();
            return VSConstants.S_OK;
        }
        else if (nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB)
        {
    
            m_exSession.GoToNextExpansionField(0); //false to support cycling through all the fields
            return VSConstants.S_OK;
        }
        else if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.CANCEL)
        {
            if (m_exSession.EndCurrentExpansion(0) == VSConstants.S_OK)
            {
                m_exSession = null;
                return VSConstants.S_OK;
            }
        }
    }
    
  8. Kullanıcı karşılık gelen kısayolu yazdığınızda ve Sekme tuşuna bastığında kod parçacığını eklemek için yöntemine Exec kod ekleyin. Kod parçacığını ekleyen özel yöntem sonraki bir adımda gösterilecektir. Önceki adımda eklediğiniz gezinti kodundan sonra aşağıdaki kodu ekleyin.

    //neither an expansion session nor a completion session is open, but we got a tab, so check whether the last word typed is a snippet shortcut 
    if (m_session == null && m_exSession == null && nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB)
    {
        //get the word that was just added 
        CaretPosition pos = m_textView.Caret.Position;
        TextExtent word = m_provider.NavigatorService.GetTextStructureNavigator(m_textView.TextBuffer).GetExtentOfWord(pos.BufferPosition - 1); //use the position 1 space back
        string textString = word.Span.GetText(); //the word that was just added
        //if it is a code snippet, insert it, otherwise carry on
        if (InsertAnyExpansion(textString, null, null))
            return VSConstants.S_OK;
    }
    
  9. Arabiriminin IVsExpansionClient yöntemlerini uygulayın. Bu uygulamada, tek ilgi çekici yöntemler ve OnItemChosen'tirEndExpansion. Diğer yöntemler yalnızca döndürmelidir S_OK.

    public int EndExpansion()
    {
        m_exSession = null;
        return VSConstants.S_OK;
    }
    
    public int FormatSpan(IVsTextLines pBuffer, TextSpan[] ts)
    {
        return VSConstants.S_OK;
    }
    
    public int GetExpansionFunction(IXMLDOMNode xmlFunctionNode, string bstrFieldName, out IVsExpansionFunction pFunc)
    {
        pFunc = null;
        return VSConstants.S_OK;
    }
    
    public int IsValidKind(IVsTextLines pBuffer, TextSpan[] ts, string bstrKind, out int pfIsValidKind)
    {
        pfIsValidKind = 1;
        return VSConstants.S_OK;
    }
    
    public int IsValidType(IVsTextLines pBuffer, TextSpan[] ts, string[] rgTypes, int iCountTypes, out int pfIsValidType)
    {
        pfIsValidType = 1;
        return VSConstants.S_OK;
    }
    
    public int OnAfterInsertion(IVsExpansionSession pSession)
    {
        return VSConstants.S_OK;
    }
    
    public int OnBeforeInsertion(IVsExpansionSession pSession)
    {
        return VSConstants.S_OK;
    }
    
    public int PositionCaretForEditing(IVsTextLines pBuffer, TextSpan[] ts)
    {
        return VSConstants.S_OK;
    }
    
  10. OnItemChosen yöntemini uygulayın. Genişletmeleri gerçekten ekleyen yardımcı yöntemi sonraki bir adımda ele alınmıştır. , TextSpan içinden IVsTextViewalabileceğiniz satır ve sütun bilgilerini sağlar.

    public int OnItemChosen(string pszTitle, string pszPath)
    {
        InsertAnyExpansion(null, pszTitle, pszPath);
        return VSConstants.S_OK;
    }
    
  11. Aşağıdaki özel yöntem, kısayola veya başlığa ve yola göre bir kod parçacığı ekler. Ardından kod parçacığı ile yöntemini çağırır InsertNamedExpansion .

    private bool InsertAnyExpansion(string shortcut, string title, string path)
    {
        //first get the location of the caret, and set up a TextSpan
        int endColumn, startLine;
        //get the column number from  the IVsTextView, not the ITextView
        m_vsTextView.GetCaretPos(out startLine, out endColumn);
    
        TextSpan addSpan = new TextSpan();
        addSpan.iStartIndex = endColumn;
        addSpan.iEndIndex = endColumn;
        addSpan.iStartLine = startLine;
        addSpan.iEndLine = startLine;
    
        if (shortcut != null) //get the expansion from the shortcut
        {
            //reset the TextSpan to the width of the shortcut, 
            //because we're going to replace the shortcut with the expansion
            addSpan.iStartIndex = addSpan.iEndIndex - shortcut.Length;
    
            m_exManager.GetExpansionByShortcut(
                this,
                new Guid(SnippetUtilities.LanguageServiceGuidStr),
                shortcut,
                m_vsTextView,
                new TextSpan[] { addSpan },
                0,
                out path,
                out title);
    
        }
        if (title != null && path != null)
        {
            IVsTextLines textLines;
            m_vsTextView.GetBuffer(out textLines);
            IVsExpansion bufferExpansion = (IVsExpansion)textLines;
    
            if (bufferExpansion != null)
            {
                int hr = bufferExpansion.InsertNamedExpansion(
                    title,
                    path,
                    addSpan,
                    this,
                    new Guid(SnippetUtilities.LanguageServiceGuidStr),
                    0,
                   out m_exSession);
                if (VSConstants.S_OK == hr)
                {
                    return true;
                }
            }
        }
        return false;
    }
    

Kod parçacığı genişletmeyi derleme ve test etme

Kod parçacığı genişletmenin projenizde çalışıp çalışmadığını test edebilirsiniz.

  1. Çözümü oluşturun. Bu projeyi hata ayıklayıcıda çalıştırdığınızda, Visual Studio'nun ikinci bir örneği başlatılır.

  2. Bir metin dosyası açın ve metin yazın.

  3. Metinde bir yere sağ tıklayın ve ardından Kod Parçacığı Ekle'ye tıklayın.

  4. Kod parçacığı seçici kullanıcı arabirimi, Test değiştirme alanları yazan bir açılır pencereyle görünmelidir. Açılır pencereye çift tıklayın.

    Aşağıdaki kod parçacığı eklenmelidir.

    MessageBox.Show("first");
    MessageBox.Show("second");
    

    Enter veya Esc tuşuna basmayın.

  5. "first" ve "second" arasında geçiş yapmak için Sekme ve Shift Sekme tuşlarına+basın.

  6. Enter veya Esc tuşuna basarak ekleme işlemini kabul edin.

  7. Metnin farklı bir bölümüne "test" yazın ve Sekme tuşuna basın. Kod parçacığı kısayolu "test" olduğundan, kod parçacığı yeniden eklenmelidir.