ReSharper, day 5: Integrated unit-test runner

Welcome to day 5 of my 31 Days of ReSharper, where I introduce you to ReSharper’s unit-test runner.

ReSharper unit test runner

(The ReSharper test runner is also available for free as a separate download, if you don’t want to buy the full-fledged ReSharper.)

Now, why would the world need another unit-test runner? There are already so many ways to run tests. There’s the NUnit GUI, and the NUnit console runner. You can (and I have) write a rakefile that builds your solution using MSBuild and then runs the NUnit console, set up a Tools menu option to invoke it, and bind a keystroke to it. You can install TestDriven.NET. (You could even pay a lot of money for Microsoft’s test runner, although it doesn’t actually let you run the tests.) Don’t these cover just about every possible option?

Well, yeah. But ReSharper’s test runner is shiny. And being an IDE add-in, it manages some nice integration. Let’s take a tour.

Running all the tests

I’ve ranted about this before, so let’s start with the number one most basic feature of a testing tool: running all the tests.

Yes, ReSharper can do it, and it’s easy. The best way to run all the tests is to bind a keystroke (we use Ctrl+Shift+T) to the ReSharperAddIn25.UnitTestRunner_RunAllSolution command. Then, any time you hit Ctrl+Shift+T, it will automatically build your solution and run all the tests, showing the green (or red) bar as it goes.

If you don’t want it to be that easy, you can also go to the ReSharper menu > Unit Testing > Run All Tests from Solution. There are a couple of other options in the Unit Testing menu, but I ignore them, as they look like they do something other than run all the tests — and so far, we’ve done pretty well at keeping our NUnit tests fast.

Supported test runners

Out of the box, ReSharper’s test runner supports NUnit and csUnit tests. There’s also a third-party add-in to add mbUnit support to ReSharper UnitRun.

Integration

The ReSharper test-runner add-in really takes full advantage of being right there in Visual Studio.

  • Dockable. The test-runner window is dockable just like all the other IDE windows, so you can tuck it out of the way. I dock it to the bottom of the IDE, in a tab-set with the Output window and the various Search Result windows. (If you put it in a tab set, and a different tab is visible when you run the tests, the test-runner window will come to the front, just like you’d want it to.)

  • Key-bindable. As I noted above, it’s terribly easy to bind a single keystroke to mean “build everything, then run all the tests, and show me the results with a red or green bar”. So easy.

  • Pays attention. When you make code changes and rebuild, all the icons in the tree turn into little question marks, so you can see that you haven’t run the tests yet. But they keep their colors, so you can still see which ones passed and failed last time around. Here are screenshots of the “freshly run” (check marks) and “after rebuild” (question marks):

    ReSharper unit test runner, showing check marks and error icons for each testReSharper unit test runner, showing question marks after building and before re-running tests

    It’s even smart enough that, if you build your solution, but you haven’t actually modified any code, it won’t switch to the question marks. (I love this, because I’m always getting distracted by a conversation or something, and then can’t remember whether I just ran the tests or not.)

  • Jump to the code. Two nice features here. First, if you double-click on a test in the test tree, the editor shows the code for that test. Secondly, if tests fail, the test results pane puts hyperlinks into the call stack, and clicking one of those hyperlinks will jump to that location in the editor.

    ReSharper unit test runner, showing a test failure message and hyperlinked call stack

  • Gutter icons to run or debug a test. Wherever ReSharper notices a test method, it will show a little green-and-yellow circle in the gutter next to the code. If you click on that circle, you’ll get a dropdown menu with, among other things, an option to run that one test under the debugger. So if you want to put a breakpoint in a test and debug just that test, it’s easy.

    ReSharper gutter icons for running unit tests

Nothing in the ReSharper unit test runner is really groundbreaking, although the “jump to the code” features are pretty nice. It’s just that the features are all there, and they’re done well. If you do unit testing, give their test runner a try.

ReSharper, day 4: Auto closing delimiters

Welcome to day 4 of my 31 Days of ReSharper.

Here’s a feature you’ll notice as soon as you start typing: when you type an opening delimiter, ReSharper will type the closing one for you.

It’s a simple feature, but not a simple one to do well, and except for a bug that they introduced in 2.5 (and then fixed in 2.5.1), they do it well. Very seldom does it do the Wrong Thing.

This works for the following delimiters: {, (, [, ", and '. It doesn’t autocomplete generic syntax, though: < is not on the list.

Here’s a sample of it at work.

Starting out with an empty statement.
You type a method name…
and type “(“.
You type a subexpression…
and type “(“.
Oops. You meant “[“, not “(“. Backspace…
and type “[“.
Once you’ve typed the parameter…
you type “]”…
then you type “)”…
and then you type “;”.

They do the things right that need doing right: when you backspace over an opening delimiter, they remove the closing delimiter (assuming you didn’t type anything inside the parens yet); and when your cursor is before the closing delimiter and you type the closing delimiter, you don’t end up with two. This also applies to semicolons; when the cursor is before a semicolon, you can type a semicolon, and you won’t get two. You can just type normally, without having to hit the right arrow all the time.

They’re even smart enough to make it work inside arbitrary nesting: if you type the opening delimiter and the closing delimiter is already there, they don’t add it. There’s got to be some guesswork involved at some point, but I don’t remember it being wrong enough to notice.

Note: When you type {, you automatically get the matching } — meaning, if your intent is to put braces around a block of code, the matching delimiter gets in your way. Instead, you can use Surround With to add the braces around the current selection. The shortcut for adding braces is Ctrl+Alt+J 8. (Ctrl+Alt+J pops up a menu, so you don’t need to memorize the “8” part.)

(Update: Ilya, one of the ReSharper developers, notes that you can have ReSharper add the closing brace when you hit Enter, instead of right away, which would make it easier to simply type braces around a block of existing code. Thanks, Ilya!)

Full list of keystrokes changed by ReSharper 2.5.1

This is a footnote to my article ReSharper survival guide, or, What’s up with my keybindings?, part of my 31 Days of ReSharper.

Key What it did in Visual Studio Alternate keystrokes in ReSharper What the key does now
Ctrl+/ (Global) Edit – Go To Find Combo Ctrl+D (Global) (Global) Tools – Go To Command Line
(Text Editor) Line Comment
Ctrl+Alt+B (Global) Debug – Breakpoints (none) Goto Inheritors
Ctrl+B (Global) Debug – Breakat Function (none) Goto Declaration In Context Menu
Ctrl+B, C (Text Editor) Edit – Clear Bookmarks Ctrl+K, Ctrl+L (Text Editor) (as Ctrl+B) Goto Declaration In Context Menu
Ctrl+B, Ctrl+C (Text Editor) Edit – Clear Bookmarks Ctrl+K, Ctrl+L (Text Editor) (as Ctrl+B) Goto Declaration In Context Menu
Ctrl+B, Ctrl+E (Text Editor) Edit – Enable Bookmark (none) (as Ctrl+B) Goto Declaration In Context Menu
Ctrl+B, E (Text Editor) Edit – Enable Bookmark (none) (as Ctrl+B) Goto Declaration In Context Menu
Ctrl+B, Ctrl+N (Text Editor) Edit – Next Bookmark Ctrl+K, Ctrl+N (Global) (as Ctrl+B) Goto Declaration In Context Menu
Ctrl+B, N (Text Editor) Edit – Next Bookmark Ctrl+K, Ctrl+N (Global) (as Ctrl+B) Goto Declaration In Context Menu
Ctrl+B, Ctrl+P (Text Editor) Edit – Previous Bookmark Ctrl+K, Ctrl+P (Global) (as Ctrl+B) Goto Declaration In Context Menu
Ctrl+B, P (Text Editor) Edit – Previous Bookmark Ctrl+K, Ctrl+P (Global) (as Ctrl+B) Goto Declaration In Context Menu
Ctrl+B, Ctrl+T (Text Editor) Edit – Toggle Bookmark Ctrl+K, Ctrl+K (Text Editor) (as Ctrl+B) Goto Declaration In Context Menu
Ctrl+B, T (Text Editor) Edit – Toggle Bookmark Ctrl+K, Ctrl+K (Text Editor) (as Ctrl+B) Goto Declaration In Context Menu
Shift+Alt+C (Global) Project – Add Class (none) (none)
Ctrl+D, A (Global) Debug – Autos Ctrl+Alt+V, A (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Ctrl+A (Global) Debug – Autos Ctrl+Alt+V, A (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, B (Global) Debug – Breakpoints (none) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Ctrl+B (Global) Debug – Breakpoints (none) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, C (Global) Debug – Call Stack Ctrl+Alt+C (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Ctrl+C (Global) Debug – Call Stack Ctrl+Alt+C (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Ctrl+D (Global) Debug – Toggle Disassembly (none) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, D (Global) Debug – Toggle Disassembly (none) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Ctrl+E (Global) Debug – Exceptions Ctrl+Alt+E (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, E (Global) Debug – Exceptions Ctrl+Alt+E (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Ctrl+I (Global) Debug – Immediate Ctrl+Alt+I (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, I (Global) Debug – Immediate Ctrl+Alt+I (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Ctrl+L (Global) Debug – Locals Ctrl+Alt+V, L (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, L (Global) Debug – Locals Ctrl+Alt+V, L (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Ctrl+M (Global) Debug – Modules (none) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, M (Global) Debug – Modules (none) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Ctrl+N (Global) Debug – Breakat Function (none) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, N (Global) Debug – Breakat Function (none) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Ctrl+P (Global) Debug – Processes Ctrl+Alt+Z (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, P (Global) Debug – Processes Ctrl+Alt+Z (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Ctrl+Q (Global) Debug – Quick Watch Ctrl+Alt+Q (Global)
Shift+F9 (Global)
(as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Q (Global) Debug – Quick Watch Ctrl+Alt+Q (Global)
Shift+F9 (Global)
(as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Ctrl+R (Global) Debug – Registers Ctrl+Alt+G (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, R (Global) Debug – Registers Ctrl+Alt+G (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Ctrl+T (Global) Debug – Threads (none) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, T (Global) Debug – Threads (none) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Ctrl+W (Global) Debug – Watch Ctrl+Alt+W, 1 (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, W (Global) Debug – Watch Ctrl+Alt+W, 1 (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Ctrl+Y (Global) Debug – Memory1 Ctrl+Alt+M, 1 (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+D, Y (Global) Debug – Memory1 Ctrl+Alt+M, 1 (Global) (as Ctrl+D) (Global) Edit – Go To Find Combo
(as Ctrl+D) (Text Editor) Duplicate Text
Ctrl+Alt+Down Arrow (Global) Window – Show Ez MDIFile List (none) Goto Next Occurence
Ctrl+Shift+E (Global) View – Resource View (none) Explore Stack Trace
Ctrl+E, A (Text Editor) Edit – Swap Anchor Ctrl+K, Ctrl+A (Text Editor) (as Ctrl+E) Goto Recent Files
Ctrl+E, Ctrl+A (Text Editor) Edit – Swap Anchor Ctrl+K, Ctrl+A (Text Editor) (as Ctrl+E) Goto Recent Files
Ctrl+E, C (Text Editor) Edit – Comment Selection Ctrl+K, Ctrl+C (Text Editor) (as Ctrl+E) Goto Recent Files
Ctrl+E, Ctrl+C (Text Editor) Edit – Comment Selection Ctrl+K, Ctrl+C (Text Editor) (as Ctrl+E) Goto Recent Files
Ctrl+E, Ctrl+D (Text Editor) Edit – Format Document Ctrl+K, Ctrl+D (Text Editor) (as Ctrl+E) Goto Recent Files
Ctrl+E, D (Text Editor) Edit – Format Document Ctrl+K, Ctrl+D (Text Editor) (as Ctrl+E) Goto Recent Files
Ctrl+E, Ctrl+F (Text Editor) Edit – Format Selection Ctrl+K, Ctrl+F (Text Editor) (as Ctrl+E) Goto Recent Files
Ctrl+E, F (Text Editor) Edit – Format Selection Ctrl+K, Ctrl+F (Text Editor) (as Ctrl+E) Goto Recent Files
Ctrl+E, Ctrl+S (Text Editor) Edit – View White Space Ctrl+R, Ctrl+W (Text Editor) (as Ctrl+E) Goto Recent Files
Ctrl+E, S (Text Editor) Edit – View White Space Ctrl+R, Ctrl+W (Text Editor) (as Ctrl+E) Goto Recent Files
Ctrl+E, Ctrl+T (Text Editor) Edit – Toggle Task List Shortcut Ctrl+K, Ctrl+H (Text Editor) (as Ctrl+E) Goto Recent Files
Ctrl+E, T (Text Editor) Edit – Toggle Task List Shortcut Ctrl+K, Ctrl+H (Text Editor) (as Ctrl+E) Goto Recent Files
Ctrl+E, Ctrl+U (Text Editor) Edit – Uncomment Selection Ctrl+K, Ctrl+U (Text Editor) (as Ctrl+E) Goto Recent Files
Ctrl+E, U (Text Editor) Edit – Uncomment Selection Ctrl+K, Ctrl+U (Text Editor) (as Ctrl+E) Goto Recent Files
Ctrl+E, Ctrl+W (Text Editor) Edit – Toggle Word Wrap (none) (as Ctrl+E) Goto Recent Files
Ctrl+E, W (Text Editor) Edit – Toggle Word Wrap (none) (as Ctrl+E) Goto Recent Files
Ctrl+E, Ctrl+\ (Text Editor) Edit – Delete Horizontal White Space Ctrl+K, Ctrl+\ (Text Editor) (as Ctrl+E) Goto Recent Files
Ctrl+E, \ (Text Editor) Edit – Delete Horizontal White Space Ctrl+K, Ctrl+\ (Text Editor) (as Ctrl+E) Goto Recent Files
Alt+Enter (Global) Class View Context Menus – Class View Project – Properties (none) Quick Fix
Ctrl+F1, C (Global) Help – Contents Ctrl+Alt+F1 (Global) (as Ctrl+F1) Help – How Do I
Ctrl+F1, Ctrl+C (Global) Help – Contents Ctrl+Alt+F1 (Global) (as Ctrl+F1) Help – How Do I
Ctrl+F1, Ctrl+D (Global) Help – Dynamic Help (none) (as Ctrl+F1) Help – How Do I
Ctrl+F1, D (Global) Help – Dynamic Help (none) (as Ctrl+F1) Help – How Do I
Ctrl+F1, Ctrl+F (Global) Help – Help Favorites (none) (as Ctrl+F1) Help – How Do I
Ctrl+F1, F (Global) Help – Help Favorites (none) (as Ctrl+F1) Help – How Do I
Ctrl+F1, Ctrl+H (Global) Help – How Do I Ctrl+F1 (Global) (as Ctrl+F1) Help – How Do I
Ctrl+F1, H (Global) Help – How Do I Ctrl+F1 (Global) (as Ctrl+F1) Help – How Do I
Ctrl+F1, Ctrl+I (Global) Help – Index Ctrl+Alt+F2 (Global) (as Ctrl+F1) Help – How Do I
Ctrl+F1, I (Global) Help – Index Ctrl+Alt+F2 (Global) (as Ctrl+F1) Help – How Do I
Ctrl+F1, Ctrl+R (Global) Help – Search Results Shift+Alt+F3 (Global) (as Ctrl+F1) Help – How Do I
Ctrl+F1, R (Global) Help – Search Results Shift+Alt+F3 (Global) (as Ctrl+F1) Help – How Do I
Ctrl+F1, Ctrl+S (Global) Help – Search Ctrl+Alt+F3 (Global) (as Ctrl+F1) Help – How Do I
Ctrl+F1, S (Global) Help – Search Ctrl+Alt+F3 (Global) (as Ctrl+F1) Help – How Do I
Ctrl+F1, Ctrl+T (Global) Help – Index Results (none) (as Ctrl+F1) Help – How Do I
Ctrl+F1, T (Global) Help – Index Results (none) (as Ctrl+F1) Help – How Do I
Ctrl+F11 (Global) Debug – Toggle Disassembly (none) Window Manager – Activate Tool – File Structure View
Ctrl+F12 (Global) Edit – Go To Declaration Ctrl+B (Text Editor, Global) Goto File Member
F12 (Global) Edit – Go To Definition (none) Goto Next Error
Shift+F12 (Global) Edit – Find All References Alt+F7 (Text Editor, Global) Goto Prev Error
F2 (Text Editor) Refactor – Rename Ctrl+R, Ctrl+R (Global) Rename
Ctrl+F6 (Global) Window – Next Document Window (none) Change Signature
F6 (Global) Build – Build Solution Ctrl+Shift+B (Global) Move
Shift+F6 (Global) Build – Build Selection (none) (Global) Window – Previous Split Pane
(Text Editor) Rename
Alt+F7 (Global) Window – Next Tool Window Nav (none) Find Usages
F7 (Global) View – View Code Enter (Class Diagram) View – Toggle Designer
Shift+Alt+F7 (Global) Window – Previous Tool Window Nav (none) Find Usages Advanced
Shift+F7 (Global) View – View Designer Shift+F7 (HTML Editor Source View) (none)
Ctrl+Shift+G (Global) Edit – Open File (none) Navigate From Here
Ctrl+Alt+H (Global) Debug – Threads (none) Type Hierarchy – Browse
Ctrl+J (Text Editor) Edit – List Members Ctrl+Space (Text Editor, Global) Live Templates – Insert
Ctrl+K, I (Text Editor) Edit – Quick Info Ctrl+K, Ctrl+I (Text Editor) (none)
Ctrl+K, Ctrl+L (Text Editor) Edit – List Members Ctrl+Space (Text Editor, Global) Edit – Clear Bookmarks
Ctrl+K, L (Text Editor) Edit – List Members Ctrl+Space (Text Editor, Global) (none)
Ctrl+K, M (Global) Edit – Generate Method Stub Ctrl+K, Ctrl+M (Global) (none)
Ctrl+K, Ctrl+P (Text Editor) Edit – Parameter Info Ctrl+P (Text Editor) (none)
Ctrl+K, P (Text Editor) Edit – Parameter Info Ctrl+P (Text Editor) (none)
Ctrl+K, Ctrl+R (Global) Edit – Find All References Alt+F7 (Text Editor, Global) View – Object Browser Go To Search Combo
Ctrl+K, R (Global) Edit – Find All References Alt+F7 (Text Editor, Global) (none)
Ctrl+K, S (Global) Edit – Surround With Ctrl+K, Ctrl+S (Global) (none)
Ctrl+K, Ctrl+W (Text Editor) Edit – Complete Word Alt+Right Arrow (Text Editor) (none)
Ctrl+K, W (Text Editor) Edit – Complete Word Alt+Right Arrow (Text Editor) (none)
Ctrl+K, X (Global) Edit – Insert Snippet Ctrl+K, Ctrl+X (Global) (none)
Ctrl+M, L (Text Editor) Edit – Toggle All Outlining Ctrl+M, Ctrl+L (Text Editor) (none)
Ctrl+M, M (Text Editor) Edit – Toggle Outlining Expansion Ctrl+M, Ctrl+M (Text Editor) (none)
Ctrl+M, O (Text Editor) Edit – Collapseto Definitions Ctrl+M, Ctrl+O (Text Editor) (none)
Ctrl+M, P (Text Editor) Edit – Stop Outlining Ctrl+M, Ctrl+P (Text Editor) (none)
Ctrl+N (Global) File – New File (none) Goto Type
Ctrl+Shift+N (Global) File – New Project (none) Goto File
Ctrl+Alt+O (Global) View – Output (none) Optimize Usings
Ctrl+Shift+P (Global) Tools – Run Temporary Macro (none) Parameter Info – Go To Previous Signature
Ctrl+Q (Global) Data – Run Selection (none) Quick Doc
Ctrl+Shift+R (Global) Tools – Record Temporary Macro (none) Refactor This
Ctrl+R, E (Global) Refactor – Encapsulate Field Ctrl+R, Ctrl+E (Global) (none)
Ctrl+R, I (Global) Refactor – Extract Interface Ctrl+R, Ctrl+I (Global) (none)
Ctrl+R, M (Global) Refactor – Extract Method Ctrl+R, Ctrl+M (Global) (none)
Ctrl+R, O (Global) Refactor – Reorder Parameters Ctrl+R, Ctrl+O (Global) (none)
Ctrl+R, P (Global) Refactor – Promote Local Variable Ctrl+R, Ctrl+P (Global) (none)
Ctrl+R, R (Global) Refactor – Rename Ctrl+R, Ctrl+R (Global) (none)
Ctrl+R, V (Global) Refactor – Remove Parameters Ctrl+R, Ctrl+V (Global) (none)
Ctrl+Shift+Space (Text Editor) Edit – Parameter Info Ctrl+P (Text Editor) Complete Code Smart
Ctrl+Space (Text Editor) Edit – Complete Word Alt+Right Arrow (Text Editor) Complete Code Basic
Ctrl+Shift+T (Global) Macros – My Macros – Recording Module – Run All Tests (none) Goto Type Declaration
Shift+Tab (Global) Edit – Select Previous Control (none) Live Templates – Go To Prev Hotspot
Shift+Tab (Text Editor) Edit – Tab Left Shift+Tab (Windows Forms Designer, Report Designer) Live Templates – Go To Prev Hotspot
Ctrl+Alt+U (Global) Debug – Modules (none) Window Manager – Activate Tool – Search Results Window
Ctrl+U (Text Editor) Edit – Make Lowercase (none) Goto Base
Ctrl+Shift+W (Global) Edit – Select Current Word Ctrl+W (Text Editor) (Global) File – Viewin Browser
(Text Editor) Shrink Selection
Ctrl+W, A (Global) View – Command Window Ctrl+Alt+A (Global) (as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+A (Global) View – Command Window Ctrl+Alt+A (Global) (as Ctrl+W) Extend Selection
Ctrl+W, B (Global) View – Bookmark Window Ctrl+K, Ctrl+W (Global) (as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+B (Global) View – Bookmark Window Ctrl+K, Ctrl+W (Global) (as Ctrl+W) Extend Selection
Ctrl+W, C (Global) View – Class View Ctrl+Shift+C (Global) (as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+C (Global) View – Class View Ctrl+Shift+C (Global) (as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+D (Global) View – Code Definition Window Ctrl+\, Ctrl+D (Global)
Ctrl+\, D (Global)
(as Ctrl+W) Extend Selection
Ctrl+W, D (Global) View – Code Definition Window Ctrl+\, Ctrl+D (Global)
Ctrl+\, D (Global)
(as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+E (Global) View – Error List Ctrl+\, Ctrl+E (Global)
Ctrl+\, E (Global)
(as Ctrl+W) Extend Selection
Ctrl+W, E (Global) View – Error List Ctrl+\, Ctrl+E (Global)
Ctrl+\, E (Global)
(as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+G (Global) View – Pending Checkins (none) (as Ctrl+W) Extend Selection
Ctrl+W, G (Global) View – Pending Checkins (none) (as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+J (Global) View – Object Browser Ctrl+Alt+J (Global) (as Ctrl+W) Extend Selection
Ctrl+W, J (Global) View – Object Browser Ctrl+Alt+J (Global) (as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+L (Global) View – Server Explorer Ctrl+Alt+S (Global) (as Ctrl+W) Extend Selection
Ctrl+W, L (Global) View – Server Explorer Ctrl+Alt+S (Global) (as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+O (Global) View – Output (none) (as Ctrl+W) Extend Selection
Ctrl+W, O (Global) View – Output (none) (as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+P (Global) View – Properties Window F4 (Global) (as Ctrl+W) Extend Selection
Ctrl+W, P (Global) View – Properties Window F4 (Global) (as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+Q (Global) View – Find Symbol Results Ctrl+Alt+F12 (Global) (as Ctrl+W) Extend Selection
Ctrl+W, Q (Global) View – Find Symbol Results Ctrl+Alt+F12 (Global) (as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+R (Global) View – Resource View (none) (as Ctrl+W) Extend Selection
Ctrl+W, R (Global) View – Resource View (none) (as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+S (Global) View – Solution Explorer Ctrl+Alt+L (Global) (as Ctrl+W) Extend Selection
Ctrl+W, S (Global) View – Solution Explorer Ctrl+Alt+L (Global) (as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+T (Global) View – Task List Ctrl+\, Ctrl+T (Global)
Ctrl+\, T (Global)
(as Ctrl+W) Extend Selection
Ctrl+W, T (Global) View – Task List Ctrl+\, Ctrl+T (Global)
Ctrl+\, T (Global)
(as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+U (Global) View – Document Outline Ctrl+Alt+T (Global) (as Ctrl+W) Extend Selection
Ctrl+W, U (Global) View – Document Outline Ctrl+Alt+T (Global) (as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+W (Global) View – Web Browser Ctrl+Alt+R (Global) (as Ctrl+W) Extend Selection
Ctrl+W, W (Global) View – Web Browser Ctrl+Alt+R (Global) (as Ctrl+W) Extend Selection
Ctrl+W, Ctrl+X (Global) View – Toolbox Ctrl+Alt+X (Global) (as Ctrl+W) Extend Selection
Ctrl+W, X (Global) View – Toolbox Ctrl+Alt+X (Global) (as Ctrl+W) Extend Selection

ReSharper, day 3: ReSharper survival guide, or, What’s up with my keybindings?

Welcome to day 3 of my 31 Days of ReSharper. (This is actually Saturday’s episode, but I’m posting it Friday evening because I’ll be out of town on Saturday.)

ReSharper is awesome. But if you’re going to use it — especially version 2.5.x (the latest version at this writing) — you need to read this Survival Guide first.

See, Visual Studio is full of keyboard shortcuts. ReSharper changes a significant number of them. And you need to know what changed and how to deal with it.

ReSharper 2.0 just silently hijacked your key bindings. ReSharper 2.5 asks nicely whether it’s OK for it to hijack your keybindings, the first time you use each keystroke; but it gives you no way to go back and change your answer — which is almost worse, because you could end up stuck without a good way to access some of ReSharper’s best features.

So before you start using ReSharper, you need a Keybinding Survival Guide. This is it.

Surviving ReSharper’s politeness

Really, there are only two things to worry about. One is the changes in high-traffic shortcuts, of which there are only a few; I cover them below. The other is the ReSharper Shortcut Conflict dialog.

As I noted above, ReSharper asks nicely whether it can take over any given shortcut. The problem is, it asks you the first time you use that shortcut, at which point you’re almost certainly in the middle of actually doing something, and in no mood to answer a silly question. Add in the fact that there’s no undo for whatever answer you give, and that they don’t even tell you what other key you should use instead, and you’re left with a pretty lousy user experience.

(Don’t get me wrong. ReSharper is an awesome tool. You just have to get past this dialog box before you can start using it.)

Based on my own experience, I think your best bet is to accept all of ReSharper’s shortcuts. Then you can either learn the new shortcuts for anything that changed, or go back in and re-map anything you can’t live without. And you can tell ReSharper to quit interrupting you with this silly dialog box.

So after you install ReSharper, I suggest opening up a solution, putting the cursor in a parameter list somewhere, and hitting Ctrl+Shift+Space. The “ReSharper Shortcut Conflict” dialog will pop up.

ReSharper Shortcut Conflict dialog

Leave the setting at “Use ReSharper command”, check the “Apply to all ReSharper shortcuts” checkbox, and hit OK.

And there you go. One problem survived: it won’t be bugging you again.

Now all you have to do is learn the keystrokes that changed.

The changed keybindings, part I: High-traffic keys

I did the research, so you don’t have to. Here are the keystrokes you need the most:

  • Ctrl+Shift+Space no longer brings up Parameter Info. Use Ctrl+P (ReSharper’s enhanced parameter info) instead. It’s better anyway — especially when you’re facing Death By Overload in System.Drawing.
    • Ctrl+Shift+Space is now a variation on Ctrl+Space, which I’ll discuss later in the month when I talk about the Ctrl+Space family.
  • F12 (Go to Definition) and Ctrl+F12 (Go to Declaration) (what’s the difference, anyway?) are replaced by Ctrl+B. You can also use Ctrl+Click.
  • Shift+F12 (Find References) is now Alt+F7 (Find Usages). Usually they found alternate shortcuts that were better than the originals… obviously not in this case. Honestly, F7?
    • F12 and Shift+F12 now step forwards and backwards through the errors and warnings in a document.
  • Ctrl+Shift+R to record a temporary macro, and Ctrl+Shift+P to play it back, are no longer available. This one hurts; I wish they’d kept them as Ctrl+Alt+Shift+R or something.
    • Ctrl+Shift+P is now Parameter Info – Go to Previous Signature.
    • Ctrl+Shift+R is now Refactor This, and is the main reason I’m not too upset about losing the keystroke for recording macros. You’ll use this far more often than macros, trust me.

Part II: Other notable changes

Here are some other things that most people probably don’t use every day, but that are still significant enough to be worth noting.

  • Some Ctrl+key prefixes (Ctrl+B, Ctrl+D, Ctrl+E, Ctrl+F1, and Ctrl+W) are now commands in their own right, not prefixes. For example, Ctrl+B Ctrl+C used to clear bookmarks, but Ctrl+B is now Go to Declaration, so multi-key Ctrl+B commands are no longer available. Visual Studio already provides alternate keystrokes for many of these (e.g., many of the Ctrl+B commands are also available through Ctrl+K), and ReSharper adds its own alternate keystrokes for a handful of them.
    • Ctrl+B is now Go to Declaration.
    • Ctrl+D is now Duplicate Text.
    • Ctrl+E is now Go to Recent Files.
    • Ctrl+F1 is now Help – How Do I (formerly Ctrl+F1 H).
    • Ctrl+W is now Select Word / Extend Selection.
  • If you used Ctrl+Alt+Down Arrow to show the MDI list (same as clicking the down arrow at the top right of the document area), that keystroke is no longer available.
    • Ctrl+Alt+Up Arrow and Ctrl+Alt+Down Arrow are now Go to Previous Occurrence and Go to Next Occurrence.
  • Ctrl+/ to go to the Find combo (did anybody actually use that?) isn’t there anymore. Ctrl+D still brings it up, but only if the focus isn’t in the editor window.
    • Ctrl+/ is now Comment / Uncomment Selection.
  • F7 (View Code) and Shift+F7 (View Designer) are now just F7 to toggle between the two. Yay!
  • F6 no longer builds the solution. Use Ctrl+Shift+B instead.

Those are the short lists. I also made a complete list of every keybinding that changed when I installed ReSharper. This list only shows the keys that were changed or removed, not the ones that were completely added. Even so, it’s a long list. But if you find a keystroke that used to work and now does something weird, check out the full list. (Note that I had Ctrl+Shift+T bound to a macro to run tests; I think that Visual Studio binds it to something else by default, Swap Words or something weird like that.)

ReSharper, day 2: The color bar and the green box

Welcome to day 2 of my 31 Days of ReSharper.

So I talked about the grays in day 1. The next thing you’ll notice, after you install ReSharper, is the color bar.

ReSharper: green box
ReSharper: green box
ReSharper: green box

Whenever you’re editing a source file, a color bar will appear next to the vertical scroll bar. There’s a little box at the top, which can be green, yellow, or red. The ReSharper docs refer to this whole assemblage as the “marker bar”.

Wherever there’s a line of code with gray in it, ReSharper shows a little yellow tick mark. Wherever there’s a line of code with compiler errors, ReSharper shows a red tick mark. These are proportionally spaced throughout the bar (the color bar doesn’t scroll; its height represents your entire source file), so if you’ve got a source file with a lot of lines of code, the tick marks will be spaced closer together.

The little box at the top is there to quickly show you the status of the entire file. If there are any compiler errors (red ticks in the color bar) in this source file, the box is red. If there are no errors, but there are ReSharper warnings (yellow ticks in the color bar), the box is yellow. The object of the game is to make the box green.

ReSharper: green box

Of course, it doesn’t stop at pretty colors. ReSharper is there to help you code, and so it does. You can hover over one of the tick marks to see a hint, describing the problem. You can also click on a tick mark, which will position the cursor on the line of code in question.

Better yet, you can use F12 to move to the next problem in the file. (Shift+F12 moves to the previous problem.)

The only downside to this feature is that it’s per-file. There’s no easy way to see whether the entire project (or solution) has a green box, and pretty soon you’ll start wishing for that feature!

Here’s a tip: you can multi-select in Solution Explorer. So click on the first source file in your project, then Shift+click on the last one, and press Enter. This will open all your files in the editor, each in its own tab. Then start closing files (Ctrl+F4), keeping an eye on the color box. As soon as you hit one that’s not green, it’s time to get to work.

Lite Brites shut down Boston

Apparently, Boston police can’t tell the difference between a billboard and a bomb.

I’m not kidding. Cartoon Network put blinking signs around several cities, advertising one of their shows. Most cities, having seen signs before, didn’t bat an eye. Boston? Mass hysteria. Highways, bridges, and river traffic shut down while police sent in bomb squads. I kid you not.

I read the news article first, and then I went to get Schneier’s take on the Boston billboard panic.

From Schneier’s post:

To advertise the Cartoon Network show “Aqua Teen Hunger Force,” the network put up 38 blinking signs (kind of like Lite Brites) around the Boston area. The Boston police decided — with absolutely no supporting evidence — that these were bombs and shut down parts of the city.

“It had a very sinister appearance,” [Massachusetts Attorney General Martha] Coakley told reporters. “It had a battery behind it, and wires.”

For heavens sake, don’t let her inside a Radio Shack.

ReSharper, day 1: The gray, the red, and the squiggly

Welcome to the first of my 31 Days of ReSharper. In these first few posts, I’ll give you a general overview of the out-of-box experience: the first things you’ll notice after you install.

These first two days will be about shiny things. Then Day Three will be important: it’s the “ReSharper survival guide, or, What’s up with my keybindings?” After that, it’s back to the shiny.

So you’ve just installed ReSharper and opened up a solution in Visual Studio. Chances are, the first thing you’ll notice is all the grays.

ReSharper: gray namespaces
ReSharper: gray code

ReSharper also has reds and squigglies, but you probably won’t see those just yet. But it’s cool: you will once you start coding.

Grays are the first thing you’ll see, but I’ll describe the squigglies and the reds first. I’ll leave the grays till last, because they’re the coolest.

Since these first few days are just an overview of ReSharper, I’ll be saying “I’ll cover this later” a lot. Right now I’m just trying to give you a flavor of the first things you’ll see, not an in-depth guidebook. The depth will come later.

The reds and the squigglies: real-time compiler errors

When you have code that won’t compile, ReSharper will show it either in red, or with squiggly underlines.

“Big deal,” you may say. “Visual Studio already has squigglies like that.” True. But Visual Studio only shows the squigglies after you compile. ReSharper points out compiler errors in real-time, as you type. It does its magic completely in the background.

You can see the error message by hovering the mouse over the red or squiggly (you’ll see a tooltip), or using the cursor keys to put the cursor inside the red or squiggly (the error will be shown on the status bar).

ReSharper: reds and squigglies

The difference between the reds and the squigglies: red is only for identifiers that can’t be found — class names, method names, variable names, etc. Squigglies are for all other sorts of compiler errors.

Identifiers are shown differently because ReSharper has special features to help you fix them. I’ll cover the reds in one of my later posts about that wonderful Swiss Army knife, Alt+Enter.

The grays: finding dead code

A couple of years ago, our code base was full of functions that were never used, but that we were afraid to delete because we “might need them someday”. We had entire units that were never used. We had commented-out code, that had been commented out for years, that we were afraid to delete.

We have since embraced the YAGNI principle — to the extent that, whenever we find unused code, we delete it without a second thought. That’s probably why we love the “grays” feature of ReSharper (called “warnings” in their docs).

ReSharper finds the code you don’t need, and shows it in gray.

ReSharper: gray unread variable
ReSharper: gray unused override

Namespace “using”s that you don’t actually need. Variables that you don’t use. Parameters that you don’t use. Unused private methods, properties, and fields. Qualifiers (“this.” and “Some.Namespace.”) that aren’t needed. Variables that you write to, but never read. Overrides that do nothing but call inherited. All gray, and most likely safe to delete. And again, it does this in real time.

The rules are, of course, configurable. If your shop’s coding standards say that you should use “this.”, then you can disable that warning in ReSharper. The options are in the ReSharper menu > Options > Highlighting.

ReSharper also has tools to help you fix these warnings. Most of them take two keystrokes, one of which is Enter. Again, I’ll go into this later in the month, when I cover Ctrl+Alt+F, Alt+Enter, and the context menu in Solution Explorer.

One could wish that it went further, and showed you everything that you don’t use — even if it’s public, show it in gray if nothing in the solution ever uses it. (Granted, that wouldn’t be for everybody — library developers wouldn’t want such a feature. We develop applications for sale, so we would love it.) Alas, they don’t have an automated way to do this. Pity. (But they do have something close: Safe Delete. I’ll cover it, yes, later in the month.)

It’s amazing how quickly you get used to the color-coding. Now, whenever we’re developing in Delphi and notice that a parameter isn’t used, we’ll joke, “Oh. It’s gray. So we’ll just hit Alt+Enter, and…”

ReSharper, day 0: Basics and installation

I figured that, before I got too far into my 31 Days of ReSharper, I’d cover the dull stuff that nevertheless is worth covering. Feel free to skip ahead to Day 1 (though if you do install ReSharper, you might want to at least skim this post).

IDEs and versions

The latest versions of ReSharper will only work with Visual Studio 2005. There’s an older version still available that works for Visual Studio 2003, but it doesn’t have all the coolest features.

As of this writing, the latest version of ReSharper (which came out less than a week ago) was 2.5.1. It fixed several minor bugs in 2.5, which means I have a little less material than I’d figured on, since I’d been planning to talk about how to work around some of the annoyances. On the other hand, 2.5.1 seems to have broken a couple of minor things that worked in 2.5 (which I’ve already reported to them).

Stuff to know about installation

Be warned: the first time you install ReSharper, it will prompt you to install a Visual Studio hotfix. This takes for-freaking-ever. It’s been a while since we installed it on our work PCs, so I don’t remember how long it took there; but I recently installed it on my home laptop, and it took (no kidding) more than four hours. Granted, my home laptop is only an 850 MHz with 256 MB of RAM, but still. Four hours. Just so you know.

(Yes, ReSharper is worth the install time. But you might want to start the install fifteen minutes before you leave work for the day, so you can click all the Yeses and then go home. ReSharper will be ready to install the next morning.)

Installing help (or not)

ReSharper’s installation wizard will ask whether you want to install its Help. They warn you that this will take a long time because they have to rebuild the indexes for all the MSDN help on your machine.

They’re not kidding about it taking a long time; it makes installation take probably half an hour or so (and that’s on our beefy 3GHz work PCs with 2 GB of RAM).

But… I don’t get it. None of ReSharper’s dialogs have Help buttons. None of them even respond to F1. And when I bring up Help from Visual Studio, I have yet to be able to find any ReSharper help topics in there. So I’m not sure just exactly what Help they’re installing!

So for ReSharper 2.5.1 at least, I’d recommend not checking the box to install Help. There doesn’t seem to be any point.

Stuff on their Web site

Their support is quite responsive. As I was writing these articles, several times I was tempted to write “Now, it would be so much cooler if ReSharper could do such-and-so…” But each time, I made myself stop writing, went to their Web site, and sent them a bug report or an enhancement request. They’re really good about responding — usually I hear something back within hours. Even if it’s “we’ll add this to our list”, it’s good to get that quick response back.

And one time, a month or two ago, their response was “We’ve added that feature; it’s in the update that’s coming out later this week.” Probably they had already added it before I even asked, but still, it’s pretty cool (and rare) for a company to be that communicative about bug reports and feature requests.

Blog event: The 31 Days of ReSharper

Note: This is about ReSharper version 2.5. R# is currently up to version 6, and has loads more stuff than I talk about here. So think of this as just the briefest introduction to what ReSharper can do.

ReSharper is a Visual Studio add-in that adds refactorings (many more than VS 2005 ships with), code cleanup, and a bunch of other conveniences. I tried downloading it a couple of years ago, opened the project we’d been working on, and it crashed. A lot has changed since then.

A few months ago, we looked at it again, and we liked what we saw. We bought a copy for everyone in the department. None of us wants to develop in Delphi anymore. (Granted, the lack of ReSharper is only one reason among many, but it’s a big one. Delphi can’t even pull off a rename refactoring, for crying out loud.)

JetBrains, the guys who make ReSharper, have a lot of info on their Web site that shows off some of the ReSharper features. But I think it’s a lot to absorb in one sitting. And besides, it could use the point-of-view of an actual, happy customer, saying “These are my absolute favorite features” instead of the complete laundry list. So I’m setting aside February on my blog for the “31 Days of ReSharper”.

Yes, I know there are only 28 days in February. But ReSharper is just that cool.

All our Visual Studio work is in C# (except for a tiny bit of C++, but ReSharper doesn’t do much for C++). So all my examples will be based around C#. ReSharper does also have a few refactorings for VB.NET, but I don’t know how extensive.

Here’s the list of the articles so far:

Marshaling Indy

We’ve got some TCP/IP client/server apps. They use a custom protocol that looks a bit like HTTP, but isn’t quite, for complicated reasons.

At present, we use Indy for all of our networking code. There are a lot of reasons for this, some of which went away over time, but the biggest reasons are (a) it’s a solid network library for Delphi, which doesn’t otherwise ship with any networking libraries beyond the Windows API, and (b) its server components are multithreaded right out of the box. Oh, and (c) it’s free.

We use the VCL version of Indy for both Win32 and .NET, because the all-.NET version didn’t exist when we started. It works quite nicely on both sides. Or did, until we tried to get all exotic.

Recently, we decided to try doing some interop between our Win32 DUnit tests and our .NET TCP server. Basically, our tests would create the server object and tell it to start listening for connections; would connect to it and do stuff; and then would shut down the server object. This would let us run end-to-end tests without actually needing to install our Windows service on the automated-build machine.

Sounds great. We wrote a C++ DLL to translate between the unmanaged and managed code, gave it a couple of exports, and fired it up. It crashed.

We tried debugging it. It died at the beginning of our server class, which descended from the Indy TCP server class. Apparently the blowup happened when our class called the inherited constructor.

I was the odd man out earlier in the week, so I played around with Hydra, to see if we just hadn’t done the C++ stuff right (or if the RemObjects people knew things we didn’t). I wrote a Hydra plug-in in .NET that let me create and shut down the server socket. This didn’t crash, but it didn’t work either: when I tried to write an app to connect to the server, it would connect and then immediately disconnect.

Weird.

Somewhere in the mix of .NET 2.0, unmanaged-to-managed interop, P/Invoked socket API calls, TThread-based threading code in .NET, and who knows what else, there be monsters. Indy, apparently, does not like interop.

And I confirmed that it was Indy, by writing my own multithreaded server socket. It worked just dandy in Hydra.

My multithreaded server was just proof-of-concept, of course; not ready for production use. We wound up doing something else. But I took some notes on what was involved in getting a multithreaded server up and running, and will probably elaborate on it and blog some of it in the future.

(Actually, getting it up and running isn’t that hard. It’s shutting it down that’s the problem.)