Code Completion Improvements in ReSharper 8July 2nd, 2013 by Dmitri Nesteruk
For those of you who have missed it, ReSharper’s code completion functions as a vastly improved version of Visual Studio’s basic IntelliSense, offering a wealth of features that improve productivity. In ReSharper 8, we’re upping the game even more with the following improvements to our completion mechanisms.
Basic Symbol Completion
In the past, referencing a yet-to-be-imported type required you to use Import Completion (Shift+Alt+Space), but not anymore! In ReSharper 8, using a type (or even its CamelHumps shorthand) that hasn’t been imported yet simply adds all the relevant entries to an ordinary code completion list:
When you choose any of the options, not only will your CamelHumps notation be replaced by the full name of the type, but a
using statement for the appropriate namespace (in this case,
System.ComponentModel) will be added to the top of the file.
Automatic symbol completion works everywhere you’d expect it to. For example, simply using an unknown type in a statement causes ReSharper to look for this type in all possible locations and offer appropriate suggestions, together with information about the namespace the type comes from, of course:
In addition, import completion will not only automatically suggest all possible types that can be used, but also all applicable extension methods, if there are any.
Also, it’s worth mentioning that items in the basic completion list include a number of ‘smart’ items such as static members applicable in the current context, generic initialization statements, and others:
Double Smart Completion
In ReSharper 8, we’re introducing a new completion paradigm, if you will, called Double Completion. The idea is that ordinary code completion shortcuts, when pressed more than once, are able to show a different set of completion values depending on how many times the completion shortcut is pressed. At each subsequent key press, new elements are added to the list, and are also highlighted with a green bar to differentiate themselves from the completion items that were already there.
Let’s start with Smart Completion (Ctrl+Alt+Space). Suppose you’re in a method of a class, and you’re assigning a
string value. Automatic completion on
this. will give you far too many elements to choose from:
Some of these members don’t even return a
string! So what we do is invoke Smart Completion and our list is substantially reduced:
But what if we press the shortcut yet again? This time round, ReSharper offers us a completion list that yields a
string for any members of the enclosing type:
In the above, for example, the
Age property is of type
int, but the completion mechanism offers to use it with
ToString(). And, since the method
GetGreeting() returns a
string, we are offered all methods of
string that themselves return a
Normalize() and so on) as completion options.
But it doesn’t stop there, because the double completion mechanism is infinite – this is what the
2xSmart label at the bottom is hinting at. Press the shortcut yet again and you’ll see the following:
That’s right – the list is expanded yet again to include a ‘3rd-order’ set of completion items. And you can keep doing this indefinitely!
Double Import Completion
We’ve already mentioned what happens during code completion for a type that is referenced from a project, but doesn’t have a
using statement. But what if a type isn’t referenced at all? Well, pressing the Import Completion shortcut once doesn’t really help us:
However, pressing the shortcut again invokes Double Import Completion. This mechanism goes off looking at all possible references, and offers completion suggestions for assemblies that can be referenced in the project:
Now, you can probably guess what happens after you choose one of these: the requisite assembly gets referenced and a corresponding
using statement is added to the top of the file.
Double Basic Completion
The Basic Completion mechanism effectively also includes Smart and Import completion mechanisms. As such, it is subject to the same double completion mechanic as those other forms of completion.
For example, you can pick an unreferenced type, press Ctrl+Space twice and you’ll see the familiar completion list:
One interesting aspect of basic completion is that, in addition to types which are visible, applying double completion also offers to complete on members which would not normally be accessible. For example:
Of course, completing a
private field would require you to change it to
internal, and ReSharper gives you a context action to do this, too.
Cast and Sender Completion
It never ends, does it? Well, there are two more subtypes of code completion that are worth mentioning individually. The first is Cast Completion, which is what happens when ReSharper knows more about the type of the variable than the current member type can tells us. Here’s a very simple example:
The above menu has been opened by pressing Ctrl+Space twice, thereby invoking the Double Completion mechanism. Using the property
Name from above will cause
employee to be cast to a type
A corollary of the above mechanism is another feature called Sender Completion. The idea is that if you have an object generating an event, the first parameter of the event handler is typically an
object. And, just like in the previous case, invoking the double completion mechanism gets you an extended list of members to choose from:
ReSharper has a handy Generate menu (Alt+Insert) but sometimes it’s nice to be able to just type something in the editor and have it generate a chunk of code without having to open any menus or windows. Indeed, this is the way Live Templates work, but now we’ve got a few of the generative actions implemented via code completion too.
First of all, completion now helps you override/implement members: in order to override or implement a member in a type, simply start typing the member name and complete the corresponding item
Then there’s the situation where you want to encapsulate a field. Instead of using the Generate action, simply type the name of the property and you will see the following completion list:
Picking either of the above options generates either a read-write property or a read-only one.
Finally, there are now handy completion options for generating fully-initializing constructors:
ctorf initializes all fields,
ctorp all properties, and
ctorfp initializes both:
Formatting Specifier Completion
One particular pain point of .NET programming is having to remember formatting specifiers for different types. Luckily, ReSharper is here to help! Completion for types with known format specifiers now offers a listing of all the usable specifiers. For example:
As you can see, the list above shows the available specifiers, their textual description, as well as a culture-neutral preview of what a formatted item would look like with this specifier.
This completion mechanism is applicable to many known .NET types (
Guid) as well as numeric types. It works both in ordinary completion statements for
ToString() as well as
Odds and Ends
There are just a few things I’d like to mention. First of all, the completion lists in all types of completion are dynamic, meaning they update their suggestions as you type.
Also, it’s now possible to define the default behavior of the Enter and Tab keys, and to control, for each of the applicable languages/technologies, whether completion happens on a Space and whether there are any symbols that ReSharper should not be completing statements on. This setting is found in ReSharper | Options | IntelliSense | Completing Characters:
Now, we all know that preprocessing directives should be avoided where possible, but if you must use them, ReSharper is here to help too.
… or a conditional compilation attribute:
Please note that for both of the above completion lists, ReSharper uses conditional compilation symbols from all available build configurations of all projects that include this particular file.