Snippets are the little shortcuts available in Visual Studio for all the different languages. Here's a well known C# code snippet in action:

image

It just shows up in Intellisense and when you hit TAB, it folds out into this:

image

So snippets are really useful and boosts productivity. You can even write your own very easily – it's just simple XML files. Here's a great walkthrough on how to create individual snippet files. It's a bit old, but the format is the same for Visual Studio 2012/2013.

Up until very recently, I was convinced that you couldn't ship snippets as part of a Visual Studio extension (.vsix). I've always thought it would be great if we could share useful code snippets but there wasn't really a vehicle for distributing them efficiently.

Then I stumbled upon a huge collection of awesome jQuery code snippets made specifically for Visual Studio. However, you had to manually download the snippets in a zip file and copy them to a specific location to work. I didn't like that. It would be so much better with a simple installer. So I decided to figure out how to create a Visual Studio extension for those snippets. Here's how to do it.

Creating the extension

The first thing you need is to download and install the SDK for Visual Studio 2012 or 2013. Then open Visual Studio and hit New Project… and select C# –> Extensibility –> VSIX Project:

image

That gives you an empty extension project containing only one file – source.extension.vsixmanifest. We need that file later.

First we need to create a suitable folder structure for our snippet files (.snippet) and we need to be very specific in the naming of our folders. Here's what the folder structure could look like when I have 2 C# snippets:

image

I've created a folder named Snippets and then added a folder for each language I want to provide snippets for. Inside each of the language folders you need to add yet a new folder and give it the name you want to show up in the Code Snippet Manager (example below is from the SideWaffle Template Pack).

image

Make sure to mark each .snippet file as Content to be included in the VSIX extension:

image

Adding a package file

Now we must add a new text file to the root of our project and call it whatever.pkgdef. We need this file to set some registry keys when the extension is installed. Any registry changes applied by the pkgdef file will automatically be reverted again when the extension is uninstalled.

If we only want C# snippets, then add the following lines to the pkgdef file:

// C# snippets
[$RootKey$\Languages\CodeExpansions\CSharp\Paths]
"MySnippets"="$PackageFolder$\Snippets\CSharp\MySnippets"

You can add more lines for other languages. Here's an example of a pkgdef file containing registry keys for all languages supporting snippets.

And finally, we must register the pkgdef file with our VSIX extension. We do that by opening the source.extension.vsixmanifest file and navigate to the Assets tab.  Then click the New button and fill in the dialog like this:

image

Then click OK. Also, make sure you have entered a name in the Author field in the .vsixmanifest file:

image

Testing it

You are now ready to test your extension. Simply hit F5 (or Ctrl+F5) to launch a new instance of Visual Studio – this is what's called the Experimental Instance which is used for extension building. It might take a minute the first time you open it.

When the experimental instance of Visual Studio is loaded, go to Tools –> Code Snippet Manager… and make sure MySnippets are loaded correctly:

image

That's it. You only need to do these steps once and every modification to existing snippets or addition of new snippets are automatically picked up and added to the extension.

Since I only wanted to provide C# snippets, I can delete all the other folders. My folder structure now looks like this:

image

Very simple and clean IMO.

The only thing left to do is to upload our extension to the Visual Studio Gallery. It's very simple and all we need is to build our project and locate the output file MySnippets.vsix in the bin folder.

image

The bin folder may contain a few other files, but we are only interested in the .vsix file since this is the one to upload to the Gallery. 

I hope this helps clarify thing a bit. Have fun writing snippets!

URL rewrites ing web.configI recently upgraded MiniBlog from using WebPages/Razor 2 to version 3. The upgrade was completely painless. I just upgraded the NuGet package and it didn't even touch my web.config. Thumbs up to the Razor team for that!

Everything seemed to work fine, but then I noticed that my root-relative links such as <a href="~/category/web-essentials"> didn't work correctly anymore. The ~/ no longer pointed to the root of my web application, but instead to the first path segment of my URL. So, when the browser was at /post/my-post, then the ~/ in my link would resolve to <a href="/post/category/web-essentials">. This was wrong.

The reason is that I use URL rewrites in my web.config to map /post/whatever to /index.cshtml?slug=whatever and that was the reason for this strange behavior. Here's my rewrite rule:

<rule name="slug" stopProcessing="true">
  <match url="^post/(.*)" ignoreCase="true"/>
  <action type="Rewrite" url="/index.cshtml?slug={R:1}"/>
< /rule>

So in order to use WebPages/Razor 3 with URL rewrites like mine, I had to tell Razor to ignore the <rewrite> segment in my web.config. That's easily done in global.asax like so:

public void Application_BeginRequest(object sender, EventArgs e)
{
     Context.Items["IIS_WasUrlRewritten"] = "false";
}

Now Razor correctly maps to the root of the website when using ~/.  

Not all cases

This little workaround is only needed if your URL rewrites happen in the path of the URL, but not if you use sub-domain rewrites. For instance, if you use URL rewrites to map sub.domain.com into domain.com/sub then it all works fine and you don't need this workaround.