Mark Miller
  • Creating the Ultimate Developer’s Keyboard–Part 4

    Here’s what we’ve done so far:

    1. In part 1, we introduced the challenge, discussed hardware options, and revealed the prototype.
    2. In part 2, we wrote our first features (before the keyboard even arrived!) to help us enter paired delimiters like braces, parens, and quotes.
    3. In part 3, we reviewed the keyboard, created our layout, labeled the keys, bound the features we wrote in part 2, and added new related features that added or removed braces automatically for child nodes of if statements.

    Making the Brace Keys Even Smarter

    I believe I might have some kind of obsessive compulsive behavior. Once I start thinking about something I want to fix, I obsess about it more and more until I finally have to fix it. And yesterday we built a feature that added or removed surrounding braces to orphan child statements. And while functionality was good, accessibility was overly complicated. We essentially bound a toggling feature to two different shortcuts. That’s not good. It increases our mental burden because we have to remember which of the two keys adds or removes braces. I want to remove this burden and make it so either of the two brace keys can be hit, and I want the software to intelligently invoke the appropriate refactoring (if available), and if neither refactoring is available, we can fall back to the default paired delimiter behavior we built in part 2.

    So let’s open our CR_KeyFeatures plug-in. Remember to delete the previously-built CR_KeyFeatures.dll before opening (see “Updating and Rebuilding in Future Sessions" in part 2 for steps on how to do this).

    We’re going to add a ContextProvider so we can improve our shortcut binding, and make it appear even smarter. Here’s how to do it:

    1. Open up the designer for the Plugin1.cs file.
    2. In the Toolbox, find the ContextProvider control (tip – type a part of the control name into the search box at the top).

    3. Drop the ContextProvider on the Plugin1 design surface.
    4. Fill out the following properties for the new ContextProvider:

      Property Value
      (Name) ctxBraceRefactoringAvailable
      Description Satisfied if one of the two brace refactorings are available (Remove Redundant Block Delimiters or Add Block Delimiters).
      ProviderName System\Refactorings\Brace Refactoring is Available

    5. Double-click the ContextProvider to generate an event handler for the ContextSatisfied event. Add this code:

          const string STR_RemoveRedundantBlockDelimiters = "Remove Redundant Block Delimiters";
          const string STR_AddBlockDelimiters = "Add Block Delimiters";
          const string STR_SystemRefactoringIsAvailable = "System\\Refactoring is Available({0})";
          const string STR_Refactor = "Refactor";
          private bool RemoveRedundantBlockDelimitersIsAvailable
              return CodeRush.Context.Satisfied(String.Format(STR_SystemRefactoringIsAvailable, STR_RemoveRedundantBlockDelimiters)) == ContextResult.Satisfied;
          private bool AddBlockDelimitersIsAvailable
              return CodeRush.Context.Satisfied(String.Format(STR_SystemRefactoringIsAvailable, STR_AddBlockDelimiters)) == ContextResult.Satisfied;
          private void ctxBraceRefactoringAvailable_ContextSatisfied(ContextSatisfiedEventArgs ea)
            ea.Satisfied = RemoveRedundantBlockDelimitersIsAvailable || AddBlockDelimitersIsAvailable;
    6. Next, let’s drop an Action onto the design surface. We’re going to create a single command that will apply the brace refactoring that is available.
    7. Fill out the following properties for the new Action:

      Property Value
      Name actSmartBraceRefactoring
      ActionName SmartBraceRefactoring
      Description Adds or removes braces as needed.

    8. Add the following code:

       private void actSmartBraceRefactoring_Execute(ExecuteEventArgs ea)
            if (RemoveRedundantBlockDelimitersIsAvailable)
              CodeRush.Command.Execute(STR_Refactor, STR_RemoveRedundantBlockDelimiters);
            else if (AddBlockDelimitersIsAvailable)
              CodeRush.Command.Execute(STR_Refactor, STR_AddBlockDelimiters);
              CodeRush.Command.Execute("Edit.LineUp");    // Put the caret on the previous line.
              CodeRush.Command.Execute("Edit.LineEnd");    // Put the caret after the opening brace (so Remove Redundant Block Delimiters is immediately available).
    9. Nice. Now, let’s try it out. Run your plug-in to start up a new instance of Visual Studio.

    Now this works like I want it to. If I want to add or remove redundant braces, I simply hit either brace key. If I want to embed a selection in braces, I simply hit either brace key (the key I hit determines the active part of the selection). If I want to add new braces I simply hit either brace key (the key I hit determines whether I want the caret inside the braces or after them). Context differentiates.

    Six different powerful but related features. Two keys. Simple.

    Recent Edits Navigation

    Two of the features I use in Visual Studio frequently are the View.NavigateForward and View.NavigateBackward commands. In my install these keys are bound to Ctrl+- (Ctrl+Minus key) and Ctrl+Shift+- (Ctrl+Shift+Minus key). I want to improve these features in a two small ways:

    1. I want to make them more accessible (improving both discoverability and efficiency) by featuring them prominently on the keyboard, with a dedicated key for each direction.
    2. I want to improve the feature with a LocatorBeacon so your eyes and brain find the target location with less cognitive effort.

    So to do this we need two Actions that will effectively wrap Visual Studio’s view navigation commands. Here are the steps in detail:

    1. Open up the designer for the Plugin1.cs file.
    2. From the Visual Studio Toolbox window, drop an Action onto the Plugin1 design surface.

    3. Fill out the following properties for the new Action:

      Property Value
      Name actNavViewBack
      ActionName NavViewBack
      Description Jumps to previous edit points in the code.
    4. Double-click the Action to generate a handler for its Execute event. Add this code to the handler:

       private void actNavViewBack_Execute(ExecuteEventArgs ea)
         showBeaconAfterNextMove = true;
    5. Drop another Action onto the Plugin1.cs design surface.
    6. Fill out the following properties for this second Action:

      Property Value
      Name actNavViewForward
      ActionName NavViewForward
      Description Jumps to later edit points in the code.
    7. Double-click the Action to generate a handler for its Execute event. Add this code to the handler:

      private void actNavViewForward_Execute(ExecuteEventArgs ea)
        showBeaconAfterNextMove = true;
    8. Activate the Plugin1.cs design surface.
    9. On the Toolbox, find and drop a LocatorBeacon control onto the design surface.


      Tip: Type “Locator” into the search box at the top of the Toolbox.

      The LocatorBeacon control draws those animated circles on the editor when collecting markers, and are useful for bringing your eyes into the right spot (especially when working with large monitors).
    10. Fill out the following properties for this LocatorBeacon:

      Property Value


      Duration 500

    11. I want this locatorBeacon to be green so it is distinctive. Inside the PlugIn1.cs source file, navigate to the InitializePlugIn method. Add the following line of code to the end of the method:

      public override void InitializePlugIn()
        locatorBeacon1.Color = DevExpress.DXCore.Platform.Drawing.Color.FromArgb(0x41, 0xBF, 0x79);
    12. Activate and then Click the Plugin1.cs design surface. The Properties window should show the main form selected.


    13. Now click the Events icon. Plugin design surfaces give you access to scores of Visual Studio and CodeRush events. There are two events we want to listen to.
    14. Double-click the CaretMoved event. Add the following code to show our new locatorBeacon when needed:

      private void PlugIn1_CaretMoved(CaretMovedEventArgs ea)
        if (showBeaconAfterNextMove)
          locatorBeacon1.Start(ea.NewPosition.TextView, ea.NewPosition.Line, ea.NewPosition.Offset);
          showBeaconAfterNextMove = false;
        else if (justShowedBeacon)
          justShowedBeacon = false;
          customerMovedCaret = true;
    15. Activate the Plugin1.cs design surface. Make sure the Properties window is listing events.
    16. Double-click the CommandExecuted event. Add the following code to immediately show the locator beacon after either Visual Studio view navigation commands are invoked:

      private void PlugIn1_CommandExecuted(CommandExecutedEventArgs ea)
        if (showBeaconAfterNextMove)
          if (ea.CommandName == "View.NavigateForward" || ea.CommandName == "View.NavigateBackward")
            showBeaconAfterNextMove = false;
            justShowedBeacon = true;
            TextView active = CodeRush.TextViews.Active;
            if (active != null)
              locatorBeacon1.Start(active, active.Caret.Line, active.Caret.Offset);

    Section Navigation

    So at the top left of the keyboard, I have four keys with icons representing member sections for Fields, Methods, Properties, and Events. I want these keys to instantly take me to the corresponding section of the active class. I anticipate this will be useful for creating new classes and also examining and understanding classes built by others. So if I hit the Methods button, it should take me to the start of the first method in the active class. Hitting that key a second time should take me to the end of that group of methods. Hitting the method key a third time should take me to the start of the next group of methods found in the file. Holding down the Shift key and hitting the Methods button should take me in the reverse direction.

    To build this feature, follow these steps:

    1. Open up the designer for the Plugin1.cs file.
    2. From the Visual Studio Toolbox window, drop an Action onto the Plugin1 design surface.


    3. Fill out the following properties for the new Action:


      (Name) actSectionJumpNext
      ActionName SectionJumpNext
      Description Jumps to the next specified section (pass the section name as a parameter – can be Methods, Properties, Fields, Events, or Constructors).

    4. Now we need to add a parameter. Double-click the Parameters (Collection)” value to bring up the Parameter Collection Editor.
    5. Click the Add button. Specify the following properties for the parameter and click OK:


      Description The section to jump to.
      Name section
      Optional False
      Type String

    6. Good. Now we need another Action to handle the jump back in the reverse direction. To save time, let’s copy this action and paste it back on the plug-in’s design surface. Change the following properties (text in red shows changes from the original Action):


      (Name) actSectionJumpPrevious
      ActionName SectionJumpPrevious
      Description Jumps to the previous specified section (pass the section name as a parameter – can be Methods, Properties, Fields, Events, or Constructors).

      The parameter remains the same.
    7. Double-click the actSectionJumpNext Action to generate an event handler for the Execute event. Add this code:

      private void actSectionJumpNext_Execute(ExecuteEventArgs ea)
        var parameter = actSectionJumpNext.Parameters.GetString("section");
        TargetSections targetSection = GetTargetSection(InitialCase(parameter));
    8. Reactivate the Plugin1.cs design surface. Double-click the actSectionJumpPrevious Action to generate an event handler for the Execute event. Add this code:

      private void actSectionJumpPrevious_Execute(ExecuteEventArgs ea)
        var parameter = actSectionJumpPrevious.Parameters.GetString("section");
        TargetSections targetSection = GetTargetSection(InitialCase(parameter));
    9. Add the following support code:

      public enum TargetSections
      static string InitialCase(string targetSection)
        if (targetSection == null || targetSection.Length < 1)
          return targetSection;
        return char.ToUpper(targetSection[0]) + targetSection.Substring(1).ToLower();
      static TargetSections GetTargetSection(string targetStr)
        if (targetStr.StartsWith("Field"))
          return TargetSections.Fields;
        else if (targetStr.StartsWith("Method"))
          return TargetSections.Methods;
        else if (targetStr.StartsWith("Constructor"))
          return TargetSections.Constructors;
        else if (targetStr.StartsWith("Event"))
          return TargetSections.Events;
        else if (targetStr.StartsWith("Propert"))
          return TargetSections.Properties;
        else if (targetStr.StartsWith("Const"))
          return TargetSections.Constants;
        else if (targetStr.StartsWith("Type"))
          return TargetSections.Types;
          return TargetSections.Unknown;
      static List<LanguageElementType > GetTypesToFind(TargetSections targetSection)
        List<LanguageElementType > typesToFind = new List<LanguageElementType>();
        if (targetSection == TargetSections.Constructors)
        else if (targetSection == TargetSections.Events)
        else if (targetSection == TargetSections.Fields)
        else if (targetSection == TargetSections.Constants)
        else if (targetSection == TargetSections.Types)
        else if (targetSection == TargetSections.Methods)
        else if (targetSection == TargetSections.Properties)
        return typesToFind;
      static void AddRange(List<SourceRange> existingRanges, SourceRange sourceRange, SourcePoint end)
        sourceRange.End = end;
      static List<SourceRange> GetExistingRanges(TargetSections targetSection, TypeDeclaration activeType)
        bool lookingForConstructor = targetSection == TargetSections.Constructors;
        List<LanguageElementType> typesToFind = GetTypesToFind(targetSection);
        bool lookingForNextSectionStart = true;
        SourceRange sourceRange = SourceRange.Empty;
        Member lastMatchingMember = null;
        List<SourceRange > existingRanges = new List<SourceRange>();
        foreach (Member member in activeType.AllMembers)
          bool foundMatchingMember = typesToFind.Contains(member.ElementType);
          if (foundMatchingMember && lookingForConstructor)
            Method method = member as Method;
            if (method != null && method.IsConstructor)
              foundMatchingMember = false;
          if (foundMatchingMember)
            lastMatchingMember = member;
            if (lookingForNextSectionStart)
              sourceRange.Start = member.Range.Start;
              lookingForNextSectionStart = false;
          else if (!lookingForNextSectionStart)
            AddRange(existingRanges, sourceRange, lastMatchingMember.Range.End);
            lookingForNextSectionStart = true;
            sourceRange = SourceRange.Empty;
            lastMatchingMember = null;
        if (!lookingForNextSectionStart)
          AddRange(existingRanges, sourceRange, lastMatchingMember.Range.End);
        return existingRanges;
      static SourcePoint GetPreviousTarget(List<SourceRange> existingRanges)
        SourcePoint target = SourcePoint.Empty;
        int activeLine = CodeRush.Caret.SourcePoint.Line;
        bool targetIsInPreviousRange = false;
        for (int i = existingRanges.Count - 1; i >= 0; i--)
          SourceRange thisRange = existingRanges[i];
          if (targetIsInPreviousRange)
            return thisRange.End;
          int startLine = thisRange.Start.Line;
          int endLine = thisRange.End.Line;
          if (activeLine == startLine)
            targetIsInPreviousRange = true;
          else if (activeLine <= endLine && activeLine > startLine)
            return thisRange.Start;
        if (targetIsInPreviousRange || target == SourcePoint.Empty)
          // We need to loop from the beginning back around to the end...
          if (existingRanges.Count > 0)
            return existingRanges[existingRanges.Count - 1].End;
        return target;
      static SourcePoint GetNextTarget(List<SourceRange> existingRanges)
        SourcePoint target = SourcePoint.Empty;
        int activeLine = CodeRush.Caret.SourcePoint.Line;
        bool targetIsInNextRange = false;
        foreach (SourceRange existingRange in existingRanges)
          if (targetIsInNextRange)
            return existingRange.Start;
          int startLine = existingRange.Start.Line;
          int endLine = existingRange.End.Line;
          if (activeLine == endLine)
            targetIsInNextRange = true;
          else if (activeLine >= startLine && activeLine < endLine)
            return existingRange.End;
        if (targetIsInNextRange || target == SourcePoint.Empty)
          // We need to loop back around to the beginning...
          if (existingRanges.Count > 0)
            return existingRanges[0].Start;
        return target;
      void SectionJump(SourcePoint target)
        if (target != SourcePoint.Empty)
          showBeaconAfterNextMove = true;
      void JumpToNextSection(TargetSections targetSection)
        TypeDeclaration activeType = CodeRush.Source.ActiveType as TypeDeclaration;
        if (activeType == null)
        SectionJump(GetNextTarget(GetExistingRanges(targetSection, activeType)));
      void JumpToPreviousSection(TargetSections targetSection)
        TypeDeclaration activeType = CodeRush.Source.ActiveType as TypeDeclaration;
        if (activeType == null)
        SectionJump(GetPreviousTarget(GetExistingRanges(targetSection, activeType)));

    This code is a bit sophisticated. It first collects the ranges of member groups inside the current class. So for example, there may be several groups of methods in a class – maybe organized by visibility, instance/static, functionality, or perhaps not organized at all. For the purposes of this code, a member range is defined as the distance between the start and end of a single member (or a group of two or more adjacent members of the same type). After collecting all those ranges, it then calculates the next position based on the desired movement direction (Previous or Next) and also based on the current position. Wrapping from the end of the last group back to the beginning of the first group is supported.

    Bonus Actions

    There are two more Actions I’ve added to the plug-in. One, called ShowURL, displays the specified web site inside the Visual Studio browser as a document.

    The other, SendKeys, will send the keys in the specified key string to the active window. Key strings can contain individual characters (e.g., a-z, A-Z, 0-9, punctuation, etc.), and can also optionally include any of the elements of the Keys enum (placed in square brackets). For example, “// Hello World[Enter]”.

    Last Minute Request – The Pizza Key

    I’m not sure why this is, but often I get requests that some might consider crazy (or surely a joke). For example, this comment came in yesterday:


    Great question, Josh! Well, as I said from the beginning, this was always expected to be a work in progress – something I would refine over time. And thanks to you, my keyboard now has a pizza key:


    The pizza key now replaces the Events icon since it was unlikely to get frequent use. If you want to print this out, here’s the image:

    (click picture above to get to full size image)

    The first time you press the Pizza key, you will see this window:


    There are very likely some locale issues here in the Quick Links to food chains that may not be in your area, however you can get full source to this plug-in and change those Quick Links if you like. And there are always the Find buttons…. Ultimately, when you decide upon a place you want, you can specify its online ordering URL in the textbox here and always have it only a single click away.



    OK, that’s it for today. Next time we’ll wrap up all the feature shortcut binding and complete the series.

  • Creating the Ultimate Developer Keyboard–Part 3

    The Keyboard Arrives.

    The keyboard is here. We’ve already created a set of features to bind to it in part 2 (and this series starts with a prototype in part 1).

    If you’ve seen me write code with an Xbox guitar before, you may have noticed how easy it was to navigate through the code. It turns out that guitars are way more intuitive at moving around code than regular keyboards are. The Xbox guitar has an up/down strum switch, and two groups of fret keys arranged in a straight line moving out from the strum key. So for navigation, I treated the fret keys like multipliers, from smallest distance moved to greatest distance moved. So to move toward the end of the file, I would strum down. With no fret keys pressed, the caret would simply move right. Depending on which fret keys were engaged, I could jump through the uppercase characters in a camel-cased identifier, through words, home/end, line up/down, up/down between methods, page up/down, as well as other special moves such as dropping and collecting markers or navigating through the history of edits. Similarly, creating and extending selections was easy. I just held down the blue fret key in combination with the other fret keys to extend the selection by the specified distance. As a result, navigating through code and refactoring with with the Xbox guitar was nirvana, and much easier and intuitive than trying to navigate with a standard keyboard.

    Of course, for entering text, the guitar doesn’t work well. And the transition time to switch to a guitar every time I need to navigate through code is too great to make it practical. However with this keyboard… I’m hoping to recreate and approach some of that nirvana in something everyone can experience.

    So at this point, I’m pretty excited.

    Hardware Review

    Upon taking the keyboard out of the package, there are few things I immediately notice. The keyboard is about 10-15% heavier and larger than I expected. This is not a showstopper for me, but something to keep in mind in case I ever collaborate on the design a custom programmer’s keyboard – something I’ve been thinking about a lot, lately.

    The second thing I notice is that pressing the keys doesn’t feel the same as pressing the keys on my Microsoft Natural keyboard. It’s a subtle difference, and I don’t have great words to describe it, so here’s a totally subjective graph showing the different forces I feel against my fingertips as I press the keys down:


    With the X-keys professional, a little more force seems to be required to push the key. As the key approaches the down state, resistance increases, then seems to ease off and the key travels faster, followed by greater resistance as the key approaches its furthest down position. The Microsoft keys, by contrast, require slightly less force (and the force required is consistent pretty much throughout the entire stroke).

    The yellow bands in the graphs above show the areas where switch contact appears to be made (and current flows through the switch below that key). With the Microsoft Natural Keyboard it feels like contact is always made in the same spot. But I don’t get the same feeling of precision with the X-keys Professional.

    I should emphasize that the differences are subtle and most developers are unlikely to notice them.

    I’m able to rationalize both of these issues as acceptable compromises in light of the productivity gains I’m anticipating, and knowing that I’m unlikely to be hitting these keys as frequently or as rapidly as the keys on my QWERTY keyboard from Microsoft.

    The rest of the keyboard however, neatly meets expectations. I can pull out keys and replace them with tall keys, wide keys, or even large square keys. I can also replace existing keys with flat key blockers.

    The keys themselves have transparent plastic covers that are easy to remove for labeling. Even though the key tops come off easily when pulled straight up, they don’t come off accidentally in response to the sheering force of my hand and fingers brushing rather aggressively against the keyboard, and they don’t come off from normal use. Nice.


    I immediately start on the layout designed in the first post in this series, adding key blockers, tall keys, and wide keys.

    KeyExtraction2 KeyBlocker KeyBlockerInstalled

    The black key blockers snap solidly into place and give me exactly that tactile feedback I am looking for.


    That was easy. Next I install the software….

    Software/SDK Review

    The included software is thorough, flexible, and ambitious, allowing you to bind multiple collections of recorded macros to the keys. Key binding collections are swapped in or out depending on which application has focus. Recorded macros can include individual key up or down transitions (not just key presses). However, I found the UI had some discoverability and clarity issues. The software also must be running to use the keyboard – a requirement I wasn’t really interested in.

    So with the included software jettisoned, I opened up their SDK to build my own options/setup pages. I don’t want to bind recorded keyboard macros to each key. Instead I want to bind actual Visual Studio and CodeRush commands (including the new features we build as part of this blog series).

    The SDK includes a C# example application that shows how to iterate through all the connected keyboards, connect to one, and setup two different callbacks: One that is called every time the data changes (a key is pressed or released), and another that is called when an error occurs (such as the keyboard getting unplugged from the USB port).

    When data changes, your callback receives an array of nine bytes. Each byte corresponds to one of the nine columns of buttons on the device. Each of those bytes contain individual bits which are set corresponding to the seven keys in that column where a button is pressed.

    I was up and running with the SDK in about an hour.

    Labeling the Keys

    Based on our design so far, the keys labels look like this (click this image for a full-size version):


    When printing this out, adjust the scale if necessary to ensure that the “1 cm” and/or “1 inch” labels are the correct length.

    I put some effort into keeping the graphic conventions consistent. For example, keys with blue backgrounds directly manipulate selections. Keys with arrows are navigation keys. Keys with blue arrows can be combined with the Shift key to extend the selection in the corresponding direction and distance. You can shrink any extended selection with the minus key:


    After some trial and error with the labels, I discovered that if I get the label shape to closely match the key shape (with the rounded corners and the lower curve), they will stay correctly oriented under the transparent tops without the need for any adhesive. This makes assembly and replacement/redesign easy.

    After printing, you simply:

    1. Cut out each key label…

    2. Remove the transparent cover…

    3. Position the label on the key….

    4. Replace the transparent cover…
    ReplacingTop  Pushing

    If you want to create your own key labels, here’s a template you can open inside any image editor (copy and paste the individual key templates as needed to match your design):


    (click the image above to see the full-size version)

    When printing, scale if needed to ensure the red and/or blue reference rectangles match their indicated lengths.


    Building the X-keys Plug-in

    To make this all work stand-alone (eliminating the need to install the X-keys software), I built an X-keys plug-in for CodeRush in Visual Studio. The plug-in consists of three parts. The X-keys Engine, the Layout options page, and the Shortcuts options page.

    X-keys Engine

    This simple engine maps the input from the custom keyboard to CodeRush or Visual Studio commands. The engine holds a buffer of keys pressed and ensures those keys are evaluated in the UI thread. This engine also adds support for repeating keys when held down, something the original software and SDK do not support.

    To customize keyboard behavior, I built two options pages….

    The Layout Options Page

    The Layout page lets you create a model of the physical key layout you decide to build. You can manually decide which keys will be blocker keys (the plastic black inserts that replace buttons), or you can click the Auto-detect Blockers button if the keyboard is plugged in which will scan the keyboard for any keys currently down and assign the Blocker attribute to each (blocked keys are always in the down position).


    Any key that isn’t blocked can be given a Key Name. This makes the settings on the Shortcuts easier to read. If you don’t name the keys, then the shortcuts options page will show the column/row data code (e.g., you’ll see “” instead of “CodeRush”).

    The other important thing to do is to specify any tall, wide, or large square keys. This is necessary because when you install a tall or wide key, you are physically connecting the key to two adjacent button stems. In a perfect world, those two keys would always fire at the same time whenever the large button above them was pressed. But in our world, either of those buttons could fire first when the key is pushed down, and either one might fire individually when the key is released. The X-keys engine that runs as part of this CodeRush plug-in exploits your layout settings, converting noise caused by two or more grouped keys making contact (e.g., when a tall or wide button is being pressed and released) into a single solid signal.

    You can download my layout settings here. Save to the X-keys subfolder inside your CodeRush settings folder. For example:

        C:\Users\YourName\AppData\Roaming\CodeRush for VS .NET\1.1\Settings.xml\X-keys

    The Shortcuts Options Page

    The X-keys Shortcuts options page is similar to the CodeRush Shortcuts dialog, allowing for organized shortcut folders, searching, and a rich context that permits a single key to have different behavior depending on where you are in the code.


    Each binding includes an optional combination of shift key modifiers (Ctrl, Alt, and/or Shift). If you want a key to fire a command when any combination of the Ctrl, Alt, or Shift keys are down, click the “Any” button. Leaving all Shift Key buttons in the up (unchecked) position means you are matching only against the X-keys key.

    Source to the X-keys engine, which includes the two options pages shown above, is available here:

    Binding our First Features

    With the X-keys CodeRush plug-in installed in Visual Studio, now it’s time to bind the Smart Paired Delimiters feature we wrote yesterday to the actual keyboard.

    On the X-keys/Shortcuts page, I want to keep shortcut bindings organized, so I create a new shortcut folder called “Paired Keys”.

    Inside this folder I create new shortcuts for each of the ten keys we have dedicated to our paired key feature. There are twelve shortcuts in all; I’m going to allow the Shift key to modify the double-quote keys so they behave like single-quote keys.

    To create a new binding:

    1. Click the New Shortcut button on the Shortcuts toolbar.
    2. Press the key you want to bind this to on the X-keys keyboard. Optionally select any needed Shift Key options.
    3. Specify the Command and any needed parameters for the shortcut.
    4. Specify the Context under which this shortcut binding is valid.

    The command for all of these features is the same: SmartPairedDelimiters

    The context for all of these bindings is also the same: Focus must be in the Code Editor.

    The parameters are all different. Refer to the screenshot below (click for full screen).


    Pro Tip: Once you get the command and context specified for one shortcut, use the Duplicate Shortcut button. Then you simply press the new X-keys key, and change the parameters as needed.

    Note: If you want to change a shortcut, just give focus to the mini keyboard layout control on this page, and then press the replacement key on the X-keys keyboard.

    If you don’t want to enter all these by hand, you can download my shortcut settings for the Paired Key bindings here. Unzip to your CodeRush settings folder.

    Now Let’s Give it a Try

    So with our new bindings in Visual Studio, let’s try out the smart delimiter features.

    Here’s an animated GIF showing some of my results:


    And just as we designed, pressing the paired delimiter key on the left places the caret inside the delimiters (inside an orange rectangular field - pressing Enter gets you out of the field), and pressing the paired delimiter key on the right places the caret after the delimiter pair.

    Let’s Take it to the Next Level

    So far, it’s not bad. I’m definitely getting the sense I would be faster and less error prone using these dedicated feature keys instead of trying to make the same thing happen on my Microsoft keyboard. But I’m also getting the feeling that we’re not done with these keys yet. There are several features I’m considering, and since it’s so easy to try this out, instead of telling you what I’m would like to do sometime in the nebulous future (e.g., tomorrow perhaps?), I’m going to do it right now.

    I’m a C# developer, and in C# an if-statement needs braces if it has more than one child statement to execute. However if it only has one child, those braces are optional. In addition to being a developer, I’m also a UI guy, so I like the code clean and easy to read. So when an if-statement has only one child, I don’t want any braces around it.

    The challenge with the if-statement and maintaining clean code, is that frequently a single child statement will need sibling statements, or you might have several child statements that can be consolidated into a single line of code (such as through Extract Method), which means the previously-needed braces are now redundant.

    So the feature I want to build right now (and bind to these dedicated brace keys) is something that instantly removes redundant braces or instantly wraps them around a single child statement. This will save time and keystrokes on an action I find myself taking regularly in the code.

    1. Bring up the X-keys/Shortcuts options page.
    2. Right-click the Paired Keys shortcut folder and select New Folder.

    3. Enter a folder name of “Redundant Braces” and click OK.
    4. Click the New Keyboard Shortcut button.
    5. Press the Close Brace (“}”) key on the X-keys keyboard.
    6. Enter the command “Refactor” with the parameters “Remove Redundant Block Delimiters”.


      You can bind to any refactoring by putting its name in the Parameters text box like this.
    7. I want this binding to simply work when I press the “}“ key (when the Remove Redundant Block Delimiters refactoring is available). But we already have a different behavior associated with this key, so we’ll need to use context to determine which action to take. In the Context Picker, scroll down to the bottom of the available contexts and click the “Refactoring is Available” context so it has a single green check in it.

    8. Right-click the “Refactoring is Available” context and choose Parameters


    9. Enter “Remove Redundant Block Delimiters” and click OK.


      Now this shortcut binding will only work when it’s possible to remove redundant braces.
    10. Let’s also constrain this binding so it only works when the code editor has focus:


    11. We have one more thing to do before we’re done. We need to disambiguate this new shortcut binding from the other “}“ shortcut added earlier. Fortunately this will be easy. First, right-click the context tree list and choose “Copy Context”.

    12. Now select the other “}” binding.

    13. Right-click this binding and choose “Paste Context”.
    14. In the context picker, scroll down to the Refactoring is Available context, and click it once more to turn it into a red “X”.

      This new context means our SmartPairedDelimiters binding will only work when the editor has focus but the Remove Redundant Block Delimiters refactoring is not available.
    15. Now, let’s create an alternate binding for the “{“ key in the same manner, this time bound to the “Add Block Delimiters” refactoring (essentially repeating steps 4-14, changing parameters to the command and the context to “Add Block Delimiters”).
    16. Click OK to save your changes.

    Let’s try it out.

    OK, so this is pretty cool. One key gives me access to three different useful functionalities, depending upon context.


    Next Time

    Tomorrow we’ll bind a number of keys to existing CodeRush and Visual Studio features (and improve some existing Visual Studio features to make them even easier to use). See you tomorrow.

  • Creating the Ultimate Developer Keyboard–Part 2

    In Part 1, I showed the hardware I intend to use and gave an preview of functionality we expect to add. I’ve ordered the keyboard and it’s on the way. While we wait for it to arrive, I’m going to create some features that we’ll bind once it gets here. I thought I would start with Paired Delimiter buttons on the left:


    This section of buttons will get us quick access to characters that often show up paired in programming. Pressing any of these keys gives you a complete pair, however the keys in the right column place the caret after the closing delimiter.

    The keys in the left column place the caret between the two characters (with a field that gets you outside when you press Enter) so you can add the code you need and get out quickly.

    Pressing either key when there is a selection embeds the selection in the pair, with the caret placed on the side of the modified text that corresponds to the column of the button that was pressed (left or right).

    So the action we’re going to build is going have one of four behaviors, depending upon whether there is a selection or not and which key you press:


    Left key pressed

    Right key pressed

    No Selection

    Inserts delimiters, caret between inside field

    Inserts delimiters, caret after (no field)

    Selection Exists

    Wraps selection in delimiters, caret at start

    Wraps selection in delimiters, caret at end

    So to make this functionality work, we will need to create a plug-in for our IDE, and in the plug-in we need to register at least one command (that we can later bind to these shortcuts) that will add paired delimiters as we’ve spec’d out.

    I’m using Visual Studio and CodeRush, but if you’re using something else, consult your extensibility documentation for how you can do the equivalent of what we’ve building here.

    1. From the DevExpress CodeRush menu, select “New Plug-in…”.
    2. Name the plug-in CR_KeyFeatures and click OK. This plug-in is going to hold all the new features we build.

      New Plug-in Project
    3. On the Project Settings dialog, click OK. No changes here. 


      The wizard will generate the plug-in project and open it. Inside Visual Studio, you’ll see a design surface where you can drop IDE-enhancing controls for your plug-in.
    4. From the DXCore section of the toolbox, drop an Action onto the design surface.


      Actions can do anything. You just provide the code. And Actions can be bound to shortcuts. You probably see where this is going. Next, we need to fill out some properties for our Action.
    5. Select the Action control if needed, and set the following properties:

      Property Value
      Name actSmartPairedDelimiters
      ActionName SmartPairedDelimiters
      Description Inserts or wraps code inside paired delimiters, passed as parameters to this action.

    6. Next, we need to add parameters to allow us to specify the leading and trailing delimiters, as well as which key was pressed – left or right. Select the Parameters property and click the “button.

    7. We’re going to add three parameters. For each parameter, click “Add”, then change the Name and Description properties as follows:

      Parameter Name Parameter Description
      LeadingDelimiter The leading delimiter to insert.
      TrailingDelimiter The trailing delimiter to insert.
      CaretPosition The position of the caret after insertion. Can be either “Left” or “Right”.

      The Parameter Collection Editor should now look like this:


      Click OK.
    8. Nice. OK, our properties are all set. Now let’s click the Events button to see the events for this action.

    9. Double-click the Execute event to attach a handler to it.

    10. Add the following code inside your event handler:

      private void actSmartPairedDelimiters_Execute(ExecuteEventArgs ea)
      string leadingDelimiter = GetParameter("LeadingDelimiter");
      string trailingDelimiter = GetParameter("TrailingDelimiter");
      CaretPlacement caretPosition = GetCaretPosition();
      if (CodeRush.Selection.Exists)
      WrapSelectionInDelimiters(leadingDelimiter, trailingDelimiter, caretPosition);
      InsertDelimiters(leadingDelimiter, trailingDelimiter, caretPosition); }

    11. Add the following support methods:

      static void WrapSelectionInDelimiters(string leadingDelimiter, string trailingDelimiter, CaretPlacement caretPosition)
        TextDocument activeTextDocument = CodeRush.Documents.ActiveTextDocument;
        if (activeTextDocument == null)

        SourcePoint savePoint = SourcePoint.Empty;
        if (caretPosition == CaretPlacement.Left)
          TextView activeView = activeTextDocument.ActiveView;
          if (activeView != null)
            savePoint = activeView.Selection.Range.Top;

        string undoMessage = String.Format("Embed {0}{1}", leadingDelimiter, trailingDelimiter);
        activeTextDocument.EmbedLineFragmentSelection(leadingDelimiter, trailingDelimiter, undoMessage, false);

        if (savePoint != SourcePoint.Empty)

      static string GetExpansion(string leadingDelimiter, string trailingDelimiter, CaretPlacement caretPosition)
        string expansion;
        if (caretPosition == CaretPlacement.Left)
          expansion = String.Format("{0}«Caret»«Field()»{1}«FinalTarget»", leadingDelimiter, trailingDelimiter);
          expansion = String.Format("{0}{1}«Caret»", leadingDelimiter, trailingDelimiter);
        return expansion;

      static void InsertDelimiters(string leadingDelimiter, string trailingDelimiter, CaretPlacement caretPosition)
        TextDocument activeTextDocument = CodeRush.Documents.ActiveTextDocument;
        if (activeTextDocument == null)

        CodeRush.UndoStack.BeginUpdate(String.Format("Smart {0}{1}", leadingDelimiter, trailingDelimiter));
          activeTextDocument.ExpandText(CodeRush.Caret.SourcePoint, GetExpansion(leadingDelimiter, trailingDelimiter, caretPosition));

      string GetParameter(string paramName)
        string parameterValue = actSmartPairedDelimiters.Parameters.GetString(paramName);
        if (parameterValue == "\\\"")    // un-escape quotes (convert \" to ").
          parameterValue = "\"";
        return parameterValue;

      CaretPlacement GetCaretPosition()
        if (GetParameter("CaretPosition") == "Right")
          return CaretPlacement.Right;
          return CaretPlacement.Left;
    12. And this enumeration:

      public enum CaretPlacement


    13. Now run the project. This will start a second instance of Visual Studio. Since we don’t have the keyboard yet, let’s test by setting up some temporary shortcut bindings to our new action. I used Ctrl+Shift+[ and Ctrl+Shift+]. Both of these shortcuts bind to the SmartPairedDelimiters command. Only the parameters change for the left and right keys.


      Here’s a list of the parameters I used to test:

      To Test: Left Key Parameters Right Key Parameters
      Smart Braces {,},Left {,},Right
      Smart Parens (,),Left


      Smart Brackets [,],Left [,],Right
      Smart Quotes \",\",Left \",\",Right
      Smart Angle Brackets <,>,Left <,>,Right

      For testing I moved the caret through the editor and pressed the shortcuts (Ctrl+Shift+[ and Ctrl+Shift+]), testing with both selections and no selection. Then I went back into the options dialog and changed the parameters for the two shortcuts and repeated.

    Updating and Rebuilding in Future Sessions

    As we progress through this series we will add new features and make changes to existing features in this plug-in. When it’s time to compile, you may see errors that the DLL is locked. This can happen when you restart the instance of Visual Studio where you built the plug-in. Restarting causes CodeRush to load all the new plug-ins, which means the plug-in you just built will be loaded into memory (and locked).

    Here’s how you can quickly delete the CR_KeyFeatures plug-in (useful whenever you need to recompile and it is locked):

    1. From inside Visual Studio’s DevExpress menu, select CodeRush | About.
    2. Right-click the Orange background and choose “Open Plug-ins folder…”.
      Two Explorer windows will appear, each containing plug-ins from two different directories.
    3. Close the About box and shut down all instances of Visual Studio.
    4. Inside the Explorer windows, find the CR_KeyFeatures.dll and delete it.

    Now you can start Visual Studio and load the CR_KeyFeatures solution to compile, edit, or debug it.

    Next Time

    OK, we’ve made some good progress. We wrote a useful feature that will be bound to ten of the keys on our keyboard. According to UPS tracking, the keyboard should be here tomorrow. So it won’t be long before we’ll be setting up the keyboard and bind our new features to the new keys. See you tomorrow.


  • Creating the Ultimate Developer Keyboard–Part 1

    So I’m a big UI guy. The science of great user interfaces has been a subject of my research for over a decade. And I write code. When any task takes more effort, precision, and/or time than what I want (e.g., anything that’s not effortless and instantaneous) I get upset.

    And even with a next generation IDE and productivity add-ins, I still get upset while coding. There are still tasks that take too long. If I think “I want to look at the fields section of my class right now”, then I want to actually be there in about 600ms or less. I don’t want to be distracted by having to remember a non-intuitive or complicated shortcut to get me there. And I don’t want to waste time doing stupid tricks (such as finding a nearby field and executing Jump to Definition) to get me close.

    In programming, there are loads of small little tasks like this one. Like moving from method to method while keeping your relative position within each method. Or navigating structurally through the code (parent/children/siblings). However dedicating unique shortcuts to these little navigations is troublesome for a few reasons. First, you have the additional burden on memory and the associated learning curve. And second, because so many shortcut bindings have already been taken by the IDE (for me, it’s Visual Studio), if you do manage to find something easy to remember that isn’t already used, chances are the next version of your IDE will take that shortcut and use it for a different feature.

    So it is in the spirit of approaching effortless and instantaneous that I embark on this multi-part blog series to try to build the ultimate programmer’s keyboard. Adding important navigation, refactoring, code-creation and testing shortcuts that are easy to discover. The keyboard will be easily configurable and have a price point of about $200. And while I’ll be using Visual Studio and CodeRush as the software hosts for this keyboard, the steps I document here should be easily portable to other IDEs.

    Getting Started

    As I mentioned, this will be a multi-part series. In each post we’ll build or integrate a feature into the keyboard, discussing good design along the way. Each feature and key will be justified in terms of savings to you, the developer. And there will be opportunities for you to go down a different path and place different keys.

    My prototype for the finished keyboard currently looks something like this:


    This is just a prototype. Some of the improvements I want to build are theoretical and need to be tested in actual code production. There may be refinements as we move forward. It is important however that every key holds its weight – each key’s feature needs to bring significant value to the developer.

    The Hardware

    There are several customizable USB keyboards to choose from. My constraints for a good customizable keyboard include:

    1. Solid, reliable key presses. The keys have to be easy to hit. It has to feel right.
    2. Sufficient keys to hold the functionality I want to add. We need about fifty keys.
    3. The ability to add double-wide or double-tall keys for important, frequently-accessed functionality (the bigger the key, the easier it is to hit).
    4. The ability to block out keys. I intend to use this for tactile feedback, so you know where you are on the keyboard without looking.
    5. Reasonably priced (e.g., <US$250).
    6. Small enough to be portable. We’re building something that can be placed on either side of the keyboard you’re already using.

    My top three contenders:

    Keyboard1 Keyboard2 Keyboard3
    XK-80 XK-60 X-keys Professional (58 keys)
    $229.95 $199.95 $189.95

    These are all from the same company. If you know of or find any other contenders, let me know. I have a feeling this search for the perfect developer productivity keyboard will be an iterative journey over the coming years. Especially since I haven’t actually placed my hands on any of these yet. I’m hoping the quality of the key presses matches expectation.

    I chose the X-keys Professional, on the right. While the other two keyboards offered an intriguing feature – the ability to optionally programmatically backlight any key with a glowing red or blue LED, I chose the non-illuminating version because of the thinner border between the key groupings. The thicker border on the XK-60 matches key size, and for me at least resulted in a visual ambiguity that I found distracting and less appealing.

    Also, at this point I don’t see a compelling reason for the backlighting in the scenarios I’m envisioning.

    The X-keys Professional is listed as “Legacy” hardware, so it may be discontinued or unavailable in the future. If that’s the case, the XK-60 and XK-80 would be my second and third choices, respectively. You can click any of the pictures above to learn more about these keyboards. If you’re nervous about that Legacy label, I bet you can easily substitute the XK-60 for the X-keys Professional I intend to use in this blog.


    The X-keys Professional comes with a key extractor, two double-tall keys and one double-wide key:


    For my prototype, I need two double-wide keys and two double-tall keys. I also need the ability to block out eight keys for that eyes-on-the-screen textile feedback I want. So in addition to the X-keys Professional, I also purchased:

    Cherry MX Switch Key Blockers – 10 for US$5

    Gray wide keycaps – 10 for US$5


    You can also purchase colored keyscaps, which could be used to emphasize important keys.


    For my prototype, I’m simply going to print out the key labels and affix them to each key, so the colored keys aren’t necessary.

    Functionality Preview

    The prototype has a number of developer-centric features and is designed for fast, one-handed access. The features are organized so similar or related features are grouped together. Also, the keyboard labels are designed to be consistent and easy to read/understand. The functional sections are previewed below.

    Refactoring, Code Declaration, Wizards, and Navigation


    The double-wide CodeRush key provides access to the Refactor/Code menu, listing available refactorings, declarations, and wizards available in the given context (determined by the selected code and/or the code surrounding the caret).

    The double-tall green Transporter key on the right provides access to context-sensitive navigation options (such as jump to Ancestor, Overloads, Instantiations, etc.).

    This section also includes arrow keys (for quick menu navigation) and the Enter key for activating selected menu items. Everything you need for fast one-handed feature access with minimum finger travel distance. And the blocked-out keys above the arrows help you line up your fingers without taking your eyes off the screen.

    Marker/Recent Edits Navigation


    These keys allow you to drop stack-based markers, collect them (with Esc), swap the current caret position with the last marker position (leaving a marker where you were, allowing for fast nearly simultaneous editing in two different places in the code), and navigate forward and backward through recently-changed blocks of code. Other features (both on this keyboard and in CodeRush) can drop markers automatically (so you can quickly get back to where you navigated away from).

    Structural Navigation


    Code has structure, and these keys let you navigate from the current node to parent, first child, and sibling nodes.



    The double-tall plus (“+”) key increases the selection by logical blocks. The minus (“-“) key decreases the selection. The swap key exchanges the caret position with the anchor, and the selected to marker key selects from the caret position to the last marker dropped. You can also extend the selection by combining the shift key with other navigation keys on this keyboard, such as the structural navigation keys shown above.

    Camel Case Navigation


    Quick access to camel case navigation. You can combine these keys with the shift key to select a portion of an identifier (frequently used when renaming).

    Reference Navigation


    Navigate forward and backward through all the references to the symbol at the caret throughout your entire solution.

    Smart Method Navigation


    Navigate across sibling methods keeping the same relative position in each method.

    Smart Pairs


    Quick access to characters that often show up as pairs in programming. Any of these keys gives you a complete pair, however the keys in the right column place the caret after the closing delimiter. The keys in the left column place the caret between the two characters (with a field that gets you outside when you press Enter) so you can add the code you need and get out quickly.

    Pressing either key when there is a selection embeds the selection in the pair, with the caret placed on the side of the selection corresponding to which of the two buttons was pressed (left or right).

    Section Navigation


    Quickly jump to sections of interest inside your class or struct. Want to get to where Fields are declared? Just press the Fields button. These keys cycle through multiple sections (in case you have fields scattered throughout your class). These keys are also designed to serve a dual filtering purpose when UIs that present members are onscreen (such as CodeRush’s Quick Nav feature or Visual Studio’s Intellisense), so if you want to see only properties listed, it’s as simple as pressing the Property key. I’m also strongly considering a third functionality – hold down Ctrl and press one of these keys to quickly declare a field, method, property or event, regardless of where the caret is in the code.

    Navigate to File, Symbol, Declaration


    These keys get you quick access to recent files, solution symbols, and an improved version of Visual Studio’s Go To Definition feature that drops a marker before drilling in (so you can get back quickly with Escape).

    Repeat Last Test Run


    The CodeRush test runner offers a number of flexible ways to test your code. You can run one or a group of tests. After you run and make changes to the code, this button will immediately repeat the last test (or group of tests) run.

    Visual Clipboard History


    One-key access to the Clipboard History.

    CodeRush Options


    One-key access to the CodeRush Options dialog.

    It’s a Prototype

    As mentioned already, this design is expected to be iterative. As I write this, I’m already thinking about changes I might make, so we’ll see where this goes. For example, I think it makes a lot of sense to add one-key toggle access to CodeRush’s Debug Visualizer (suddenly now do the background LEDs make sense?) and the Unit Test Builder. Of course, this is the beauty of this approach. If you decide to follow along with me and build this, you can swap more suitable functionality for anything that doesn’t appeal to you.

    Some of these keys will simply map into existing functionality in Visual Studio and/or CodeRush. Other keys will require new features to be built. Don’t worry, I’ll take you through all the steps so you can follow along and build them yourself if you like.

    If you’re working in Visual Studio without CodeRush, or you’re working in another IDE, you still should be able to create any missing functionality with a plug-in for your environment (so the concepts here still apply so you can still enjoy the productivity gains offered).

    And if you don’t want to build this yourself, stay tuned because I expect we’ll give away fully-configured versions of the final keyboard sometime in the near future.

    Next Time

    OK, I’ve ordered my keyboard and I’m just waiting on it to arrive. While we wait, we can start writing the new features we’ll need. Look for those in tomorrow's post.

  • Is there a Roslyn-based CodeRush in your Future?

    At this year’s //build/ conference, Microsoft announced the open-sourcing of Roslyn, their .NET compiler for the next version of Visual Studio. Roslyn supports code analysis and code generation for C# and VB.NET languages.

    CodeRush customers have enjoyed functionality similar to Roslyn, built-in and shipping since 2005. Although, unlike Roslyn, which currently supports only C# and VB, CodeRush also supports JS, HTML, XAML, CSS and other languages. That functional similarity between Roslyn and CodeRush is unlikely to be accidental. First, having first-class compiler, language analysis, and code generation available to Visual Studio extensions is a really good idea, and good ideas are bound to be validated and improved upon again and again. And second, Dustin Campbell, previously a lead developer for the CodeRush team, has moved on to Microsoft and has been a leading force on the Roslyn team since its inception.

    However, in some ways, Roslyn is better than CodeRush’s core engine. One of the things we really like is the snapshot feature, which allows several different plug-ins to safely work asynchronously with read-only images of the code taken at different points in time without blocking the UI thread. And while one of our competitors has openly worried that this will lead to excessive memory consumption, this seems extremely unlikely due to the Visual Studio team’s cleverly efficient design (where snapshots are only a little bigger than the memory required to hold the code changes that have occurred since the snapshot was taken) as well as likely real world scenarios where snapshots are never really needed for a long time, and only exist for as long as they are needed.

    The other thing we really like about Roslyn is that Microsoft has finally managed to find performance improvements that beat the same highly-optimized, high speed features we have in CodeRush, such as find all references (which serves as a foundation for many refactorings including Rename). Prior to Roslyn, CodeRush had the fastest .NET find all references (FAR) available, beating Visual Studio’s FAR time as well as all of our competitors year after year. And so we find Microsoft’s performance improvements to be impressive.

    Functional and Physical Overlap

    Since Visual Studio 2003, any Visual Studio add-in that offered refactoring features also came at a cost, in the form of less-than-ideal performance due to duplication of effort, as well as the additional memory required to hold similar information. Over the years, the CodeRush team made significant advances in the area of both performance and memory optimization. However, we always knew that no matter how hard we tried, there would always be a functionality overlap where CodeRush and Visual Studio were both doing similar work, as well as a physical overlap where CodeRush and Visual Studio were both holding similar structures in memory. And until Roslyn, this overlap was unavoidable.

    Integration Challenges

    While moving CodeRush to work more closely with Roslyn offers an interesting potential, it is fraught with challenges. For example, Roslyn only supports C# and VB, while CodeRush’s language-independent source code tree supports many more languages. There are changes required throughout the product. In some cases those changes are minor, and in other cases the changes are significant and may even impact third-party plug-ins.

    Currently CodeRush plug-ins enjoy the benefit of working with a language-independent source tree. Refactorings don’t need to know if they are working with C#, C++, VB, JavaScript, etc.; they simply work with all languages. So this extensibility model might have to change.

    CodeRush also has over 20,000 test cases, and integrating with Roslyn would likely impact those as well.

    The Decision

    We like what the Visual Studio team has done, and we see the Roslyn technology (and its expected derivatives supporting other languages) to be the foundational future of extensible IDE design. And so the CodeRush team is all-in.

    We have already started building a version of CodeRush dedicated to totally exploit everything Roslyn has to offer. CodeRush customers can expect noticeable speed improvements for a number of refactorings and core features, as well as see a dramatic reduction in memory usage (e.g. 200MB-400MB less memory consumed for most medium to large projects),

    Although this decision is ambitious, the team is taking steps to work as efficiently as possible. For example, we are prioritizing efforts to ensure the most important and the most sophisticated core features get attention first, and we are looking at ways to ensure that every one of our existing test cases remains untouched.

    As we get closer to widespread Roslyn adoption, we’ll keep you updated with our progress. By the way, Microsoft recently open-sourced the Roslyn project. To learn more, click here.

  • New in CodeRush 13.2: Unit Test Builder

    Here’s a new feature that will help you generate test cases as you’re stepping through code. You know the scenario – you’re debugging and find a problem caused by the data passed in or the state of the software. You might want to continue stepping through the code but you also want to add a test case for the method you’re in right now.

    CodeRush has a cool new feature to help out in this situation. The Unit Test Builder (UTB). Here’s how it works:

    1. You will need at least one test project referencing at least one test framework. Which framework you pick doesn’t matter. CodeRush supports them all, and the UTB supports projects with references to multiple test frameworks.
    2. Start your debugging session and get to someplace interesting. For example, here I have a call to a class that calculates prime numbers:


      As you can see from the Expression Explorer, we’re passing in 4 and the IsPrime method is returning true. Four is NOT a prime number, so this is clearly a bug. Let’s step into the IsPrime method…


      This is the method that is returning the incorrect value when the candidate parameter is four. Four is not a prime number, so it should return false instead of true. We can figure out why later, but for now we should add a test case, so we….
    3. Press Ctrl+Alt+Shift+T to generate a new test case for this method, with the data passed in matching our arguments. The Unit Test Builder will appear:

      Here you can see a list of tests that will be generated after the debugging session ends. Hovering over the method in the “Method Called” column produces a hint showing the values passed in:

    4. Let’s rename the test method. Let’s call it FourIsNotPrime.

    5. We can place this method inside a different class if we want, or we can use the existing test class, or we can create a new test fixture to hold our test method.

    6. Finally, we can add optional remarks that will appear inside an XML doc comment.


      Note that all of these steps with the UTB (4-6, above) are completely optional. You can continue to debug and add test methods without making any changes to the names of the test methods or where they will be placed.
    7. Continue to debug, and add more tests as needed.

    8. Finally, when you’re finished, stop the session or close the application you’re debugging just as you normally would. At this point all the tests we’ve added to the UTB will be generated.


      Double-click a test in the UTB to navigate to that test.
    9. Now you add the assertion code (CodeRush has templates for this – “at” yields Assert.IsTrue, and “af” gives you Assert.IsFalse, for example).

    The final code for our test fixture looks like this:

    public class CalculatorTests
      Calculator _Calc;
      public void Initialize()
        _Calc = new Calculator();
        _Calc.Owner = this;
      public void TestIsPrime5()
        int candidate = 5;
        bool result = _Calc.IsPrime(candidate);
      public void TestIsPrime10()
        int candidate = 10;
        bool result = _Calc.IsPrime(candidate);
      // These two methods were generated following the
      // steps shown above in this blog. Note that the
      // UTB is smart enough to realize that we need
      // an instance of Calculator and that this test 
      // fixture already had one. So we use that instance 
      // in the generated test methods. 
      /// <summary> 
      /// Four is not a prime number! 
      /// </summary> 
      public void FourIsNotPrime()
        int candidate = 4;
        bool result = _Calc.IsPrime(candidate);
      /// <summary> 
      /// Nine is not a prime number! 
      /// </summary> 
      public void NineIsNotPrime()
        int candidate = 9;
        bool result = _Calc.IsPrime(candidate);

    The UTB is pretty cool. Give it a try and let us know what you think.

  • Customer Request: Insert a Method’s Parameters into a Template Expansion

    The Question

    This conversation popped up on Twitter:


    The customer wants a list of parameters inserted into a CodeRush Template. CodeRush Templates are like Visual Studio code snippets on steroids.

    My first thought: “We might have this. Let me check.”


    I opened the Template Editor options page, right-clicked the template expansion area, chose “Insert StringProvider”, and entered “param” in the Filter textbox:


    Unfortunately, nothing. StringProviders are code-based helpers located in plug-ins that deliver strings of text. I close this dialog.

    CodeRush also has TextCommands, which simply execute code (any code you write) from a plug-in. Sometimes that code execution can actually insert text in the middle of a template expansion. In cases like this, a TextCommand behaves similarly to a StringProvider. So I right-clicked the template expansion area again, but this time I chose “Insert TextCommand”, and once again entering “param” into the Filter textbox:


    Unfortunately, not what we were hoping for.

    So nothing we are currently shipping outputs a list of the current method’s parameters as a string. But I know we can do this pretty easily by writing our own plug-in.

    My reply on Twitter goes out:


    I return to my work, prepping for the pending release, and then it occurs to me – we can do this without a plug-in. One of the TextCommands we do ship with CodeRush is ForEach. It iterates over structural elements in your code, calling a specified template for each element found, and also optionally calling specified templates before, between, and after each element in the list.

    With some clever template creation, we can get the customer exactly what they need.

    CodeRush’s ForEach TextCommand

    Next I bring up the CodeRush User Guide, and click the “Reference\Text Commands” node, then click the ForEach TextCommand so I can take a look at the syntax. The dynamically-generated help page (generated from the plug-in TextCommand itself) looks like this:


    The ForEach TextCommand takes two required parameters (iterationBounds and the template to expand each time an element is found), and three optional parameters (firstTemplate, betweenTemplate, and lastTemplate – all names of templates to expand).

    I want to create a simple comma-separated list of parameters. So I will only need to use betweenTemplate (to place a comma and a space between each parameter name found). Note that this template will only be called if there are two or more elements in the list.

    Making it Work

    Now things get fast and easy. Inside the template editor, I create a new template for testing, named “zzz”. This template’s expansion looks like this:

    «ForEach(Parameter in Method,#AddParameter#,,#Comma#)»

    Notes on this call:

    • Parameter in Method is the iterationBounds. That means we’re going to iterate through every parameter in the active method (the method containing the caret).
    • #AddParameter# is the name of a template I haven’t created yet. It’s going to simply insert the text of the parameter and nothing more.
    • We pass nothing in for the firstTemplate argument.
    • #Comma# is the name of a template I haven’t created yet. It’s going to simply insert a comma followed by a space.
    • As a convention, I use the hash tag symbols around templates that I call from other locations (e.g., #Comma# and #AddParameter# – but these templates could have any name you want).


    Next I create the #AddParameter# template. It looks like this:


    This references the “Get” StringProvider, which is responsible for managing a list of variables and their values during template expansion. The ForEach TextCommand defines two variables for use in Templates – itemName (the name of the item being iterated), and itemType (that particular item’s type).

    So this template is done – it’s just going to return back the name of the parameter.

    Finally, I need to create the #Comma# template. This one is simple – just a comma followed by a space. I click OK to drop the CodeRush Options dialog.


    I move the caret inside a method with some parameters and enter the name of my test template – “zzz”:


    I press the Space bar (you might press Tab if that’s your template expansion key).

    I see this:



    The last step is to rename our “zzz” template into something more meaningful (e.g., #ParameterList#). You can rename templates by pressing F2 when the template is selected inside the Template Editor options page.

    Now whenever we need a parameter list in a template, we can right-click that template expansion, choose “Insert Alias…” (a way of calling templates from templates), and select our new #ParameterList# template to insert a list of parameters.

    Going Further

    Note that if we wanted to include the parameter type with each parameter, we could do that easily by modifying the #AddParameter# template to something like this:

    «?Get(itemType)» «?Get(itemName)»

    Then our template expansion might give us something like this:



    Learning More about TextCommands

    Here’s a video webinar Rory Becker and I recorded a while back, that introduces TextCommands and also goes into several examples of what you can do with the ForEach TextCommand:


  • CodeRush Shortcut Keys

    An updated CodeRush shortcut cheat sheet (in pdf format) is available, including new default shortcuts for debugging:

    CodeRushShortcuts1   CodeRushShortcuts2

    If you need the original source (for example, you want to modify shortcuts and print out your new version) in PowerPoint format, you can get that here.

  • Getting Started with CodeRush webinar

    On Tuesday, 1 October 2013 Paul Usher and I will walk you through quickly setting up and enjoying the benefits of CodeRush. We’ll start with a fresh install with default settings, and show how to customize the environment. We’ll also provide an introduction to some of the more powerful features of the product, including templates and code providers for high speed coding, refactoring, duplicate code consolidation, and the visual debugging features.

    Register for the webinar here.

  • CodeRush 13.1 - Enhancements to the Visual Studio Debugging Experience

    With the release of CodeRush 13.1, we have made several significant enhancements to improve the Visual Studio debugging experience, shedding more light on some of the more challenging-to-discern aspects of debugging.

    XAML Bindings in Silverlight 5

    Now when stepping through Silverlight 5 XAML binding code you’ll see previews of the binding properties. Gone is the need to bring up the Locals window, open the BindingState object, and then find and open the FinalSource property. Now the information you need is right where you’re looking – in the code.

    DV in SL5 
    Instantly see binding properties without looking away from the code, reaching for the mouse, or pressing excessive keystrokes.

    Improved Support for Exceptions and the Call Stack

    To make finding bugs even easier we’ve added the Call Stack and Exceptions (CS&E) tool window. While at first it may appear to be simply an easier way to read call stacks, like CodeRush itself, it’s more than a pretty face. It is especially handy when debugging asynchronous code.

    To show how useful it is, first let’s look at the typical Visual Studio asynchronous code debugging experience. We’ll measure the impact on usability along the way – if this gets too crazy for you, you can jump ahead to the “Now let’s try it with CodeRush…” section below.

    Async Debugging Experience in Visual Studio (without CodeRush)

    First the exception is thrown. Visual Studio stops execution here:


    VS Usability Impact so far: 1 target area visually scanned, 3 seconds invested

    Hmm. That’s not very helpful. Of course, Visual Studio also presents this dialog:


    Where’s the useful information? We have no indication of what code caused the problem.

    VS Usability Impact so far: 2 target areas visually scanned, 7 seconds invested

    Next you look at the call stack. It looks like this:


    Also, not useful.

    VS Usability Impact so far: 3 target areas visually scanned, 11 seconds invested. We’re going nowhere fast.

    OK, let’s go back to that exception helper window. Let’s click the “View Detail…” link.


    VS Usability Impact so far: 1 click, 3 target areas visually scanned, 12 seconds invested

    Here comes the View Detail dialog. It looks like this:


    No useful information yet. Good thing our hand is on the mouse. Move it up to the triangle and click it.

    VS Usability Impact so far: 2 clicks, 4 target areas visually scanned, 14 seconds invested

    Now we see this:


    Scanning this data, your eyes may have noticed the InnerException. What’s that all about? Let’s open it up. Click the triangle to the left of the InnerException node.

    VS Usability Impact so far: 3 clicks, 5 target areas visually scanned, 17 seconds invested

    You probably have to resize and scroll to see this data.

    VS Usability Impact so far: 4 clicks, 1 scroll, 5 target areas visually scanned, 20 seconds invested

    The contents of that InnerException node look like this:


    OK, so it feels like we’re getting closer. After visually scanning the InnerException child nodes, we can see three important pieces of information:


    The InnerException of this InnerException is null (which means we’re near the root of the problem). The Message tells us a parameter called “address” is null, and we have a stack trace that may finally be useful.

    VS Usability Impact so far: 4 clicks, 1 scroll, 6 target areas visually scanned, 26 seconds invested, and it seems we’re almost there.

    Let’s open up that stack trace.  First, click anywhere on that StackTrace line in the dialog. Then click on the drop down button to the right. If your Visual Studio is like mine, you’ll see something like this:


    Lovely. As an exercise in futility, try to read that wrapped call stack to figure out where your problem is. There is actually more to the call stack than you see in this drop down, unfortunately there’s no scroll bar to tip you off to that fact.

    After more clicking, scrolling, and reading (both above and below the visible parts of the call stack above), we might infer that our problem is at the topmost position of the call stack that references our application code:

    WindowsFormsApplication1.MailSenderAsync.<SendEmail> in MailSenderAsync.cs (line 27)

    VS Usability Impact so far: 7 clicks, 2 scrolls, 9 target areas visually scanned, 33 seconds invested, and it seems we’re farther away than we thought.

    So now we look at the code. Since there's no navigation support built in, we need to close this stack of windows.

    VS Usability Impact so far: 10 clicks, 2 scrolls, 9 target areas visually scanned, 36 seconds invested.

    Next we need to get to line 27 of MailSenderAsync.cs and take a look:

    VS Usability Impact so far: 11 clicks, 2 scrolls, 5 keystrokes, 9 target areas visually scanned, 41 seconds invested.


    Let’s press Ctrl+Shift+Space to see the parameter tool tip for the MailAddress constructor.


    Excellent! We’ve found the parameter named “address”. Getting closer.

    VS Usability Impact so far: 12 clicks, 2 scrolls, 8 keystrokes, 9 target areas visually scanned, 44 seconds invested.

    OK, so the “sender” parameter must be null. But how did we get here? How do we fix this? Unfortunately, after almost a full minute of clicking, scanning, and reading, we’ve only scratched the surface of understanding the problem. Typically the next step is to set a conditional breakpoint to stop when sender is null so we can investigate the call stack in more detail.

    From the Usability Count we’ve been maintaining it seems we’re investing a lot of development time going nowhere. We might need to set a breakpoint and try this again, or scan the call stack from the inner exception again to find out how we got here and find out how sender is getting a null value. Even a guru developer may be several seconds, if not minutes away from discovering the answer.

    Let’s compare this experience with Visual Studio on some serious family-friendly steroids, err CodeRush, plus our new CS&E window.



    Now let’s try it with CodeRush…


    By the way, if you already have the latest version of CodeRush installed, we recommend starting a new debug session (create new project and run it) right now and then open and dock the CS&E window at your favorite place in the editor while VS is in debug mode. This one-time step will get Visual Studio to remember this position and make sure the CS&E window is there for you in future debug sessions.

    I’ll wait while you do that.

    DevExpress | (CodeRush) | Tool Windows | Call Stacks and Exceptions. Smile

    OK, ready? Here’s how easy it is to find the bug with CodeRush:

    Starting with the same code and the same place as the previous example, click this link:


    CR Usability Impact so far: 1 click, 1.5 seconds invested.

    The CS&E window immediately looks like this:


    We’re debugging Async, so we know this outer call stack isn’t interesting. Instead we click the “Show inner exception” link above the stack.

    CR Usability Impact so far: 2 clicks, 3 seconds invested.

    Now we see this:


    Do you see that? The CS&E window is ACTUALLY HIGHLIGHTING the line of code contributing to our “sender equals null” problem. No need to visually scan the call stack. Just click the “MailSenderAsync.cs line 21” link, and we’re immediately inside this code:


    Are you kidding me? The Sender field variable, the parameter to the SendMail overload is ACTUALLY SELECTED. It’s actually selected, kids, drawing your eyes right onto the source of the problem, explaining how the sender parameter became null – the Sender field variable, passed into the method from line 21, was null. Now we’re much closer to understanding the problem. Nice.

    CR Usability Impact so far: 3 clicks, 5 seconds invested.

    When you’re debugging asynchronous code, the difference is huge. Here are the usability totals for this example:

      Visual Studio (alone) VS + CodeRush
    Clicks 12+ 3
    Scrolls 2+ 0
    Keystrokes 8+ 0
    Areas Visually Scanned 9+ 0
    Time invested 44+ seconds 5 seconds

    This is good stuff. CodeRush helps you stay focused on the code instead of wasting time struggling with suboptimal UI.

    Important notes about the CS&E window:

    • Make sure you have the “Automatically paste exception or call stack from clipboard” button in the down state to get this seamless ease of use.
    • You can copy call stacks and exception data from any location (including Visual Studio’s Call Stack window).

    This last point means you can send a call stack to a team member and they can copy it to the clipboard and see it inside the CS&E window, and they can use it to explore the same version of the code, EVEN IF THEY ARE NOT DEBUGGING. Impressive.

    Dead Path De-emphasis

    CodeRush de-emphasizes code on dead paths (e.g., outside the current execution path). Conditional blocks that won’t be executed on the current pass are grayed out, so as you’re stepping through code it’s even easier to focus on the code that will be executed.

    Code along the dead path (e.g., inside the conditional block) is grayed-out. We won’t be stepping into that block in this pass.

    Recursive Method Depth Counter

    CodeRush now displays a counter indicating the depth of recursive method calls. The counter appears when a method is called from itself at least one time.

    The Recursive Method Depth counter shows how deep you are into that method’s recursive call stack.

    The recursive call indicator reveals how many times the method appears on the call stack, so “2” is shown on the first recursive call.

    New Actions, New Options, and Other Debug Visualizer Improvements

    The following actions and default shortcuts are now available:

    • Toggle Expression Values - Ctrl+Shift+Alt+F10
    • Focus Next Expression - Tab
    • Focus Previous Expression - Shift+Tab
    • ToggleDebugVisualizer - Ctrl+Alt+D

    We have added a “Show historical values” option to the “Editor | Debug | Visualizer” options page. It specifies whether to show values only for the current code line or for all code lines within the current method. I prefer seeing a full history, however you may prefer a more compact display as you work.

    In Visual Basic, CodeRush now shows icons indicating whether the current Boolean expression is true or false for “case” statements.

    The Debug Visualizer is smarter and able to automatically preview more expression types than before.

    CodeRush smoothly adjusts line height when showing or hiding debug visualizer visual elements (expression values or Expression Explorer). This results in a smoother debugging experience and keeps your eyes on the important data.

1 2 3
5 6 7 8 9 10

Chat is one of the many ways you can contact members of the DevExpress Team.
We are available Monday-Friday between 7:30am and 4:30pm Pacific Time.

If you need additional product information, write to us at or call us at +1 (818) 844-3383


DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business Application Frameworks, and Reporting Systems for Visual Studio, along with high-performance HTML JS Mobile Frameworks for developers targeting iOS, Android and Windows Phone. Whether using WPF, ASP.NET, WinForms, HTML5 or Windows 10, DevExpress tools help you build and deliver your best in the shortest time possible.

Copyright © 1998-2017 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners