Click here to Skip to main content
Click here to Skip to main content

Extending Visual Studio Part 1 - Creating Code Snippets

By , 14 Apr 2012
 

Extending Visual Studio

This article is part of the series 'Extending Visual Studio'.

Part 1 - Creating Code Snippets
Part 2 - Creating Addins
Part 3 - Item Templates  

Introduction

In this series of articles, I am going to show you some of the fantastic ways that you can extend Visual Studio. Visual Studio is amazingly extensible, there are a number of ways that you can build upon it.

In this article, we'll start with one of the simplest ways to extend Visual Studio - creating Code Snippets.

What are Code Snippets?

A code snippet is a chunk of pre-formatted code that is dropped into the editor, either inserting a new block of code or wrapping an existing block. The snippet can contain some reusable segment of code. As an example, create an empty class and type in 'ctor'. As you type, intellisense will narrow down the choices for you, here we can see a snippet:

extendingvisualstudio1/SnippetScreenshot.png

Now press tab twice. The 'ctor' snippet creates the class constructor. You can create all sorts of snippets, let's get started.

The Brief

First let's define what we want the snippet to do. Look at the code below - here you can see two Notifying Properties from my Apex Library.

private NotifyingProperty firstNameProperty =
    new NotifyingProperty("FirstName", typeof(string), string.Empty);

public string FirstName
{
    get { return (string)GetValue(firstNameProperty); }
    set { SetValue(firstNameProperty, value); }
}

private NotifyingProperty secondNameProperty =
    new NotifyingProperty("SecondName", typeof(string), string.Empty);

public string SecondName
{
    get { return (string)GetValue(secondNameProperty); }
    set { SetValue(secondNameProperty, value); }
}

I use these properties all over my code - so this is the ideal candidate for a code snippet. The majority of the code is the same in every case, the only thing that will change is:

  • The name of the property
  • The type of the property

Creating the Snippet

In the example project, I have added the snippet files to a blank C# project - however, we don't need any specific type of project to create a snippet, it's just a bit of XML. Create a new XML file and rename it InsertApexNotifyingProperty.snippet. Use the boilerplate below to get started.

<?xml version="1.0" encoding="utf-8" ?> 
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/CodeSnippet">
    <CodeSnippet Format="1.0.0">

        <!-- The header contains information describing the snippet. -->
        <Header>
          
          <!-- The Title of the snippet, this will be shown in the snippets manager. -->
          <Title>Insert Notifying Property</Title>
          
          <!-- The description of the snippet. -->
          <Description>Inserts an Apex Notifying Property.</Description>
          
          <!-- The author of the snippet. -->
          <Author>Dave Kerr</Author>
          
          <!-- The set of characters that must be keyed in to insert the snippet. -->
          <Shortcut>apexnp</Shortcut>
          
          <!-- A URL for more help. -->
          <HelpUrl>http://apex.codeplex.com</HelpUrl>
          
          <!-- The set of snippet types we're dealing with - either Expansion or -->
          <SnippetTypes>
            <SnippetType>Expansion</SnippetType>
          </SnippetTypes>          
          
        </Header>
      
        <!-- Now we have the snippet itself. -->
        <Snippet>
                    
            <!-- Sepecify the code language and the actual snippet content. -->
            <Code Language="CSharp" Kind="any">
                <![CDATA[

                    // My first snippet!
                    
                ]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

You may find this boilerplate useful - a link to it is at the top of the page.

Note for Visual Basic: If you're creating a VB code snippet, the in the 'Code' tag, change 'Language' from 'CSharp' to 'VB'. 

So what have we done here? Just created some summary data for the snippet and a very basic piece of content.

Installing the Snippet

Choose 'Tools > Code Snippet Manager' and then select 'Import' - browse to your newly created snippet. Now in any code window, you can key in 'apexnp' and you get the comment '// My first snippet'. Not bad!

extendingvisualstudio1/CodeSnippetsManager.png

Adding Parameters

Let's generalise the code that we want to create. Insert the code below into the snippet file in the 'Code' tag.

private NotifyingProperty PropertyNameProperty =
    new NotifyingProperty("PropertyName", typeof(PropertyType), default(PropertyType));

public PropertyType PropertyName
{
    get { return (PropertyType)GetValue(PropertyNameProperty); }
    set { SetValue(PropertyNameProperty, value); }
}

I've highlighted the key points in red and blue - there are actually only two segments of code we need to replace, the PropertyName and PropertyType strings.

Modify the snippet definition so it looks like this:

<!-- Now we have the snippet itself. -->
<Snippet>

  <!-- Create any declarations that we use in the snippet. -->
  <Declarations>
    <Literal>
      <ID>PropertyName</ID>
      <ToolTip>Enter the property name</ToolTip>
      <Default>PropertyName</Default>
    </Literal>
    <Literal>
      <ID>PropertyType</ID>
      <ToolTip>Enter the property name</ToolTip>
      <Default>PropertyType</Default>
    </Literal>
  </Declarations>

  <!-- Sepecify the code language and the actual snippet content. -->
  <Code Language="CSharp" Kind="any">
    <![CDATA[
                private NotifyingProperty $PropertyName$Property = 
                  new NotifyingProperty("$PropertyName$", typeof($PropertyType$), default($PropertyType$));
                
                public $PropertyType$ $PropertyName$
                {
                  get { return ($PropertyType$)GetValue($PropertyName$Property); }
                  set { SetValue($PropertyName$Property, value); }
                }
            ]]>
  </Code>
</Snippet>

We've added two Literal tags. Literals are replaced in each segment of code. The first part of a literal is the ID - this is what we must surround in dollar signs in the Code tag. The second part is the tooltip that is displayed. The final part is the default value for the snippet. Let's see our updated snippet in action.

extendingvisualstudio1/FinalScreenshot.png

Perfect! It all works exactly as it should.

Installing the Snippet

We can create an installer for the snippet by first creating another XML file named .vscontent. It should look like this:

<?xml version="1.0" encoding="utf-8" ?>
<VSContent xmlns="http://schemas.microsoft.com/developer/vscontent/2005" >
  <Content>
    <FileName>InsertApexNotifyingProperty.snippet</FileName>
    <DisplayName>Insert Apex Notifying Property</DisplayName>
    <Description>Inserts an Apex Notifying Property</Description>
    <FileContentType>Code Snippet</FileContentType>
    <ContentVersion>2.0</ContentVersion>
    <Attributes>
      <Attribute name="lang" value="csharp"/>
    </Attributes>
  </Content>
</VSContent>

Note for Visual Basic: If you need to install a Visual Basic snippet - use 'vb' as the 'value' part of the 'attribute' tag. 

The final thing to do is add the .vscontent and .snippet file into a new *.zip file and rename it from zip to vsi. This creates a VSI installer - double click on it and you get the below:

extendingvisualstudio1/ContentInstaller.png

Important Nnte: If you get an exception when running the installer, do you have the Windows Phone Developer Toolkit installed? If so, post on http://social.msdn.microsoft.com/Forums/en-US/vsx/thread/6504fde1-b84d-4e4f-80f9-54f6a5596fc0/ and kick up a stink so that Microsoft fixes this bug!

If you need to display publisher information, you must sign the VSI file, some more details are available here: http://msdn.microsoft.com/en-us/library/ms246580.aspx.

Final Thoughts

I hope you enjoyed this article, keep your eyes on my blog for news of the next in the series, www.dwmkerr.com.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Dave Kerr
Software Developer
United Kingdom United Kingdom
Member
Follow my blog at www.dwmkerr.com and find out about my charity at www.childrenshomesnepal.org.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 4memberMember 391382325 Dec '12 - 20:14 
Easy to read and straight to the point
GeneralRe: My vote of 4mvpDave Kerr28 Dec '12 - 1:07 
Well I'm glad you liked it Smile | :)

QuestionVery usefull post but how to make it dynamic?membermabanza1 Aug '12 - 7:42 
Hi there
Still not clear how to make it dynamic, i.e. insert any word rather than Age in your example? Do I modify XML each time and import it?
I need to automate a simple thing:
 
private TYPE aNAME;
public TYPE NAME
{
get {return aNAME;}
set {aNAME=value;}
}
so the TYPE and NAME must be dynamic.
Thanks.
GeneralRe: Very usefull post but how to make it dynamic?mvpDave Kerr6 Aug '12 - 4:59 
Hi,
 
By default, it is dynamic. If you change the XML in the example to the XML at the end of the post, it'll work fine - you key in 'type' and 'name' after you've inserted the snippet, and it'll automatically set them in the snippet for you. So in the screenshot in the article, 'Age' is in yellow - when you type over 'Age' you get the text replaced, then press tag and you can overwrite 'type' Smile | :)
 

<!-- Now we have the snippet itself. -->
<Snippet>
 
  <!-- Create any declarations that we use in the snippet. -->
  <Declarations>
    <Literal>
      <ID>Name</ID>
      <ToolTip>Enter the property name</ToolTip>
      <Default>Name</Default>
    </Literal>
    <Literal>
      <ID>Type</ID>
      <ToolTip>Enter the property name</ToolTip>
      <Default>Type</Default>
    </Literal>
  </Declarations>
 
  <!-- Sepecify the code language and the actual snippet content. -->
  <Code Language="CSharp" Kind="any">
    <![CDATA[	
				private $Type$ _$Name$;
				public $Type$ $Name$
				{
				get {return $Name$;}
				set {$Name$=value;}
				}
            ]]>
  </Code>
</Snippet>

GeneralRe: Very usefull post but how to make it dynamic?membermabanza8 Aug '12 - 3:02 
Hi Dave
It is not working. I have the snippet as following:
 
<Declarations>
        <Literal>
          <ID>Name</ID>
          <ToolTip>Enter the property name</ToolTip>
          <Default>Name</Default>
        </Literal>
        <Literal>
          <ID>Type</ID>
          <ToolTip>Enter the property name</ToolTip>
          <Default>Type</Default>
        </Literal>
      </Declarations>
      <!-- Now we have the snippet itself. -->
        <Snippet>
 
            <!-- Sepecify the code language and the actual snippet content. -->
            <Code Language="CSharp" Kind="any">
                <![CDATA[
                private $Type$ _$Name$;
        [ORM("$Name$")]
                public $Type$ $Name$
                {
                get {return $Name$;}
                set
        {
          $Name$=value;
          OnPropertyChanged(new PropertyChangedEventArgs($Name$));
        }
                }
            ]]>
 

            </Code>
        </Snippet>
 
Ant it gives me the following in the VS Editor (I cite the class name to show you the scope):
 
public partial class CareLevelControl : DictionaryCustomBase
{
...

private _;
[ORM("")]
public
{
get {return ;}
set
{
=value;
OnPropertyChanged(new PropertyChangedEventArgs());
}
}
 
Why id does not expand my declarations?
Thanks.
GeneralRe: Very usefull post but how to make it dynamic?mvpDave Kerr8 Aug '12 - 3:24 
This is very strange - can you try using the propfull snippet? it comes with VS by default, key in 'propfull' and hit tab twice - does this work?

GeneralRe: Very usefull post but how to make it dynamic?membersandeshjkota12 May '13 - 23:46 
This is because the <Declarations> tag is out of <Snippet> tag
 
This should work:
<Snippet>
<Declarations>
        <Literal>
          <ID>Name</ID>
          <ToolTip>Enter the property name</ToolTip>
          <Default>Name</Default>
        </Literal>
        <Literal>
          <ID>Type</ID>
          <ToolTip>Enter the property name</ToolTip>
          <Default>Type</Default>
        </Literal>
      </Declarations>
            <!-- Sepecify the code language and the actual snippet content. -->
            <Code Language="CSharp" Kind="any">
                <![CDATA[
                private $Type$ _$Name$;
        [ORM("$Name$")]
                public $Type$ $Name$
                {
                get {return $Name$;}
                set
        {
          $Name$=value;
          OnPropertyChanged(new PropertyChangedEventArgs($Name$));
        }
                }
            ]]>
 

            </Code>
        </Snippet>

GeneralMy vote of 5memberMihai MOGA12 May '12 - 18:30 
This is a great inspiring article. I am pretty much pleased with your good work. You put really very helpful information. Keep it up once again.
GeneralRe: My vote of 5mvpDave Kerr6 Aug '12 - 4:55 
Thanks very much! Smile | :)

GeneralMy vote of 5memberrctaubert14 Apr '12 - 3:11 
Good information.
GeneralRe: My vote of 5mvpDave Kerr6 Aug '12 - 4:55 
Thanks, glad you like it!

QuestionLanguage typememberrctaubert13 Apr '12 - 7:08 
If you want to create a snippet for VB.net what do you use for Language? VB or VB.net or ???
 

AnswerRe: Language typemvpDave Kerr14 Apr '12 - 0:01 
Hi,
 
If you want a VB code snippet, then in the snippet XML use:
 
  <Code Language="VB" Kind="any">
    <![CDATA[
                ' Put your VB here!
            ]]>
  </Code>
 
One final thing, when you create your VSContent XML - use 'vb' as the 'lang' attribute:
 
<VSContent xmlns="http://schemas.microsoft.com/developer/vscontent/2005">
    <Content>
        <!-- etc -->
        <Attributes>
            <Attribute name="lang" value="vb"/>
        </Attributes>
    </Content>
</VSContent>
 
Does this help?

AnswerRe: Language typemvpDave Kerr14 Apr '12 - 0:04 
I've also updated the article with a couple of notes for VB Smile | :)

GeneralRe: Language typememberrctaubert14 Apr '12 - 3:10 
Thank you for your reply.
QuestionDon't suppose you knowmvpSacha Barber3 Feb '12 - 23:48 
How you could install a snippet and interact with editor using DTE and VS addin programatically without getting user to install snippet do you?
Sacha Barber
  • Microsoft Visual C# MVP 2008-2012
  • Codeproject MVP 2008-2011
Open Source Projects
Cinch SL/WPF MVVM

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue
 
My Blog : sachabarber.net

AnswerRe: Don't suppose you knowmvpDave Kerr3 Feb '12 - 23:54 
I've looked into this - I was rather hoping the main DTE2 interface would provide a programmatic means of enumerating and modifying snippets. Alas I have had no success along this line of enquiry. I suppose there may be more functionality in this area coming along with VS2011 and Roslyn but until then I'm not sure I'm afraid - have you had any luck?

GeneralRe: Don't suppose you knowmvpSacha Barber4 Feb '12 - 0:55 
Just started to look into it, so not yet, but I will. Where there is a will there is a way. Working with Pete O'Hanlon has been awesome his addin skills are very handy
Sacha Barber
  • Microsoft Visual C# MVP 2008-2012
  • Codeproject MVP 2008-2011
Open Source Projects
Cinch SL/WPF MVVM

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue
 
My Blog : sachabarber.net

GeneralRe: Don't suppose you knowmvpDave Kerr4 Feb '12 - 1:40 
Cool well do let me know when you work it out - aye that Pete O'Hanlon surely knows his stuff! You working on a project together? Anything interesting?

GeneralRe: Don't suppose you knowmvpSacha Barber4 Feb '12 - 5:46 
Yeah working on project together, can't give too much away but V1 is so nearly done. Soon
Sacha Barber
  • Microsoft Visual C# MVP 2008-2012
  • Codeproject MVP 2008-2011
Open Source Projects
Cinch SL/WPF MVVM

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue
 
My Blog : sachabarber.net

AnswerRe: Don't suppose you knowmemberMike Hankey4 Feb '12 - 5:47 
I started to create a Snippet Manager for the new AVR Studio 5.0 but got side-tracked.
Unfortunately I had ot reload my system so lost all my Zotero links but
you might check this[^] out. If I remember right
I was using it as reference.

GeneralRe: Don't suppose you knowmvpSacha Barber4 Feb '12 - 6:00 
Cool thanks
Sacha Barber
  • Microsoft Visual C# MVP 2008-2012
  • Codeproject MVP 2008-2011
Open Source Projects
Cinch SL/WPF MVVM

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue
 
My Blog : sachabarber.net

QuestionFound new snippet to vsi convertermemberMember 432946910 Dec '11 - 10:56 
Best converter for snippet to vsi converter can be downloaded from Snippet To Vsi Converter


For more information Snippet To Vsi Converter Blog
AnswerRe: Found new snippet to vsi convertermvpDave Kerr3 Feb '12 - 23:54 
Very nice Smile | :)

GeneralUseful...memberjanhavib7 Dec '11 - 19:10 
Other options are... http://snippetdesigner.codeplex.com/[^]
 
or http://snippeteditor.codeplex.com/[^]
 
http://exportascodesnippet.codeplex.com/[^]

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 14 Apr 2012
Article Copyright 2011 by Dave Kerr
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid