Writing ReSharper 4.5.x Macros

While working on the MVC Marathon, I decided to try out ReSharper and write some good templates to make my time unit testing in ASP.NET MVC a little quicker. I soon realized that I needed a macro that would turn the unit test class name (HomeControllerTests) into the name of the controller being tested (HomeController).

Since ReSharper only has a few macros that will make copies of other template variables, I started scouring the internet for clues and found this post. It’s a little outdate for ReSharper for 4.5, so here’s what I had to do to make my custom macro.

You can download the source or fork your own on GitHub.

Creating the Macro

  1. Create a new C# class library project.
  2. Add references to the following dlls:
    JetBrains.Platform.ReSharper.UI.dll
    JetBrains.ReSharper.Feature.Services.dll
  3. Add a new class to your project and mark it with the Macro attribute and implement the IMacro interface:
    using System;
    using System.Collections.Generic;
    using System.Text.RegularExpressions;
    using JetBrains.ReSharper.Feature.Services.LiveTemplates.Macros;
    using JetBrains.ReSharper.Feature.Services.LiveTemplates.Hotspots;
    
    namespace ChrisLaco.ReSharper.Macros
    {
        // {#0:pattern}, etc are arguments that are passed to EvaluateQuickResult arguments[]
        [Macro("applyRegex", ShortDescription = "Replace string matching {#0:pattern} with {#1:string} in {#2:variable}", LongDescription = "Applies regex to replace value in another template variable.")]
        class ApplyRegexMacro : IMacro
        {
            #region IMacro Members
    
            public string EvaluateQuickResult(IHotspotContext context, IList<string> arguments)
            {
                if (arguments.Count != 3)
                {
                    return null;
                }
                else
                {
                    try
                    {
                        // Using the regex argument, replate the value of the specified template variable with the specified string
                        var result = Regex.Replace(arguments[2], arguments[0], arguments[1], RegexOptions.IgnoreCase);
    
                        return result;
                    }
                    catch (Exception e)
                    {
                        return "<" + e.Message + ">";
                    }
                }
            }
    
            public HotspotItems GetLookupItems(IHotspotContext context, IList<string> arguments)
            {
                return null;
            }
    
            public string GetPlaceholder()
            {
                return "a";
            }
    
            public bool HandleExpansion(IHotspotContext context, IList<string> arguments)
            {
                return false;
            }
    
            // Must return the same # of parameters declared in the Macro
            public ParameterInfo[] Parameters
            {
                get
                {
                    return new[] { new ParameterInfo(ParameterType.String), new ParameterInfo(ParameterType.String), new ParameterInfo(ParameterType.VariableReference) };
                }
            }
    
            #endregion
        }
    }
  4. In AssemblyInfo.cs, apply assembly attributes for the ReSharper plugin manager:
    using System.Reflection;
    using System.Runtime.InteropServices;
    using JetBrains.UI.Application.PluginSupport;
    
    [assembly: PluginTitle("ChrisLaco.ReSharper.Macros")]
    [assembly: PluginDescription("Provides additional template macros: ApplyRegexMacro.")]
    [assembly: PluginVendor("Christopher H. Laco")]

    This information will be displayed in the ReSharper -> Plugins dialag:

    ReSharper Plugin Manager

  5. To install plugin, simply copy the compiled dll into one of the follow directories:
    C:\Documents and Settings\username\Application Data\JetBrains\ReSharper\v4.5\vs9.0\Plugins
    C:\Program Files\JetBrains\ReSharper\v4.5\Bin\Plugins

Using the Macro

  1. Select the macro from the list of available macros:Choose Macro
  2. Click on the macro variables to set them:Set Macro Variables
  3. Finish up the template text and savr your changes:Apply Macro to Template
This entry was posted in Articles and tagged , . Bookmark the permalink.

3 Responses to Writing ReSharper 4.5.x Macros

  1. John Miller says:

    Good stuff! Haven’t created a resharper macro before, impressed at how easy it looks.

    Have you used their live templates in the past? That coupled with some Auto-Hotkey macros (for bdd test naming styles) has been the sweet spot for me. http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/02/26/seamless-test-authoring-with-resharper-and-autohotkey.aspx

  2. claco says:

    To be honest, I not a fan of those underscores. I tend to stick with CanLoadIndex() instead of Can_Load_Index().

    I’m not sure what the fetish with underscores are, esp. when it’s recommeded to use – instead of _ in friendly urls between words.

    Go figure.

  3. John Miller says:

    You learn to love ‘em :) . A big selling point is that I can use a simple tool to generate reports from the tests by simply replacing “_” with ” “.

    kinda ugly, I agree. But good enough til we can use IronRuby & RSpec to write unit tests against .Net code :) .