Partager via


ExpansionProvider Class

Provides support for inserting code snippets into source code.

Namespace:  Microsoft.VisualStudio.Package
Assemblies:   Microsoft.VisualStudio.Package.LanguageService (in Microsoft.VisualStudio.Package.LanguageService.dll)
  Microsoft.VisualStudio.Package.LanguageService.9.0 (in Microsoft.VisualStudio.Package.LanguageService.9.0.dll)

Syntax

<ComVisibleAttribute(True)> _
<CLSCompliantAttribute(False)> _
Public Class ExpansionProvider _
    Implements IDisposable, IVsExpansionClient

Dim instance As ExpansionProvider
[ComVisibleAttribute(true)]
[CLSCompliantAttribute(false)]
public class ExpansionProvider : IDisposable, 
    IVsExpansionClient
[ComVisibleAttribute(true)]
[CLSCompliantAttribute(false)]
public ref class ExpansionProvider : IDisposable, 
    IVsExpansionClient
public class ExpansionProvider implements IDisposable, IVsExpansionClient

Remarks

A code snippet is a template that is expanded into full code when the user inserts the snippet. When the snippet is first expanded, the Visual Studio core editor enters a special template editing mode where the snippet can be modified in place. That is, certain parts of the snippet are designated as fields, and these fields can easily be changed by the user before the snippet is committed to the editor's buffer. The fields are highlighted and can feature drop-down boxes offering choices to the user.

A snippet has a name to identify it and a template file containing the snippet itself. The template file contains XML tags indicating specific elements of the template, from the code to substitution fields to functions (known as expansion functions). See Creating and Using IntelliSense Code Snippets for more details on code snippets.

Notes to Implementers:

The ExpansionProvider class provides all the support for selecting and inserting a code snippet into a source file. The base class provides all the basic functionality; however, if you want to support context-sensitive snippet insertion (that is, a snippet with the same name might behave differently depending on the context into which it is inserted), then you must derive a class from the ExpansionProvider class and override the IsValidType and IsValidKind methods to report the appropriate snippet type and kind that are allowed in a particular context. Be sure to override the CreateExpansionProvider method in your version of the LanguageService class to return your version of the ExpansionProvider class.

Notes to Callers:

An instance of the ExpansionProvider class is returned from the CreateExpansionProvider method in the LanguageService class that is called from the GetExpansionProvider method in the Source class. The ViewFilter class calls its own GetExpansionProvider that in turn forwards the call to the GetExpansionProvider method in the Source class. The ViewFilter class calls the GetExpansionProvider method any time a command is executed to allow the ExpansionProvider class a chance to act.

Examples

Expansions are inserted in three ways:

  1. The code snippet browser,

  2. Selecting a snippet shortcut name from a completion list, or

  3. By typing a shortcut and entering a completion character such as a tab or space.

The following example shows one way to handle auto-expansion that is triggered by typing an expansion shortcut followed by the tab key. This method is called every time a tab key is typed.

using Microsoft.VisualStudio.Package;
using Microsoft.VisualStudio;

namespace MyLanguagePackage
{
    class MyViewFilter : ViewFilter
    {
        // This is called from our HandlePreExec when a tab key is pressed
        bool HandleTabKey()
        {
            ExpansionProvider ep = GetExpansionProvider();
            if (ep == null || ep.InTemplateEditingMode)
            {
                // No expansion provider or already editing a template,
                // so nothing to do.
                return false;
            }

            TokenInfo tokenInfo = Source.GetTokenInfo(TextView);
            if (tokenInfo.StartLine != tokenInfo.EndLine ||
                tokenInfo.StartIndex == tokenInfo.EndIndex)
            {
                // No shortcut found before caret, so nothing to do.
                // Note that the above test does not allow for single
                // character tokens to be shortcut names.
                return false;
            }

            int line;
            int col;
            int hr;
            hr = TextView.GetCaretPos(out line,out col);
            if (hr != VsConstants.S_OK)
            {
                // Could not get current position, so nothing to do.
                // GetCaretPos is used in Source.GetTokenInfo so if
                // GetCaretPos fails, GetTokenInfo fails. However,
                // better to be thorough and test again here.
                return false;
            }

            // Get shortcut text that was just typed.
            string shortcut = Source.GetText(line,
                                             tokenInfo.StartIndex,
                                             line,
                                             tokenInfo.EndIndex);
            if (shortcut == null || shortcut == "")
            {
                // No text was found at the position. This failure is
                // is not likely if GetTokenInfo returned a valid token
                // but better to be thorough.
                return false;
            }

            string snippetTitle;
            string snippetPath;
            TextSpan pos = new TextSpan();
            pos.iStartLine = line;
            pos.iStartIndex = tokenInfo.StartIndex;
            pos.iEndLine = line;
            pos.iEndIndex = tokenInfo.EndIndex;
            if (ep.FindExpansionByShortcut(TextView,
                                            shortcut,
                                            pos,
                                            true,
                                            out title,
                                            out path) != VSConstants.S_OK)
            {
                // No snippet matched the shortcut, so nothing to do.
                return false;
            }

            // If InsertNamedExpansion returns true, snippet was
            // inserted and therefore the Tab key was handled.
            // Otherwise, false is returned and the Tab key will be
            // passed on to someone else.
            return ep.InsertNamedExpansion(TextView,
                                           title,
                                           path,
                                           pos,
                                           false);
        }
    }
}

Inheritance Hierarchy

System.Object
  Microsoft.VisualStudio.Package.ExpansionProvider

Thread Safety

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

See Also

Concepts

Creating and Using IntelliSense Code Snippets

Code Snippets Schema Reference

Reference

ExpansionProvider Members

Microsoft.VisualStudio.Package Namespace