Another idea for the C# editor

I was pitching this idea to the team about a new feature we could have for the C# editor, but I wanted to get your ideas on it. Whether you think it's good, or bad, or things you think it might do instead. If you liked it I would add it to that list we've been working on for things to add to C#.

Basically I've been trying to figure out ways to help users in two areas:. error correction and discoverability of code. Error correction seems like something we should be a lot better at considering we have an immense understanding of your code, and the context surrounding the error should be quite helpful in figuring out what you probably meant to write. Helping with discoverability should also be something we do considering that we know about the entire system. Basically, if we know so much, why do we help so little?

Part of the problem is that we don't want to be in your face all the time. Sometimes you just want to code and not be bothered. How many times do you get mad at Word because you're typing some stuff and all of a sudden it mucks around with it and you have to fix it? In our opinions that kind of interference could be a deal breaker for many coders. We've gone slightly against that model with 2005 to test the waters and get feedback from you guys as to whether or not you like it, hate it, or are just ok with it. We've done it in two ways. One is by bringing up a completion list automatically when you're typing an identifier, and the other is through the use of smart tags that can help you based on what you've just done with the code. 

Bringing up a completion list automatically when typing an identifier seems like a pretty basic idea. You want to type “Console.WriteLine”, so you start hitting “C” and the completion list is up, the typing of “o” will get you to “Console” and you can know just hit 'enter'. When you get used to it it makes for some pretty damn quick typing. However, it can be a nuisance if you are doing something like typing a call to a method that doesn't exists yet. In that case you'll have to hit 'esc' to get the completion list to disappear. (This is similar with what happens in VS2002/3 when you have a completion list up because you hit <dot> and you type something that isn't in the list). One of the things we learned quickly with this feature was that if we didn't list all relevant information in a completion list then this would drive you crazy. For example if we didn't include “out” in the completion list when you were typing a method then instead of typing “out int param” you'd type “OutOfMemoryException int param” because the “o” would bring up the completion list and “out” would select that exception. Because of this we worked very hard to make sure that at any point in your code we would know everything that was valid to type at that point. The only times we'd screw up would be if you were coding in a forward thinking style where you were using things before you'd ever declared them (of course, we already screwed this up in the past, so we weren't too worried).

The smart tags come about in a few places. Mainly when we want to alert you that we could help you out based on what you've just typed. For example if you have a class called “Foo” and you go to the name, delete it and type “Bar” you'll get a smart tag that when invoked offers to rename all things that used to refer to “Foo” to now refer to “Bar” instead. Other examples are when we see that you've typed a method call to a method that doesn't exist. We'll offer to generate the stub of that method for you in the appropriate location. We'll also now give you a smart tag offering to add a using when you use a type from a namespace you don't currently have a using for. 

In order to make these features truly useful we had to work very hard to make sure that at edit time we really had a very strong understanding of the system. This was necessary otherwise we'd just be in the way causing you to get code you didn't intend to write and also bothering you with unhelpful smart tags (i.e. a smart tag to add a using you already have would just aggravate you).

Because of these enhancements to the core architecture I was able to take the help one step further. Specifically I spiked a spell checker into the IDE. It has a few cool (IMO) features and I wanted your feedback on it. A picture might help out a little:


As you can see the smart tag is broken into three areas. The first two are the ones you might have already seen in the current releases. They offer, respectively, possible using‘s and fully qualified name replacements for the unbound item. The third area is new. It is the section that uses some heuristics to determine what you might have meant if you type a name that we cannot bind. As you can see, the spelling can be way off and we will still offer relevant correction. Also the replacement we offer does not have to be a type or namespace, but can be anything legal in C# at that point:

We do aggressive scanning of the system to see what you might have wanted to type, and we try to sort by relevance:

As you can see, we’ve found the your local variable “xmlReader” and we offer it first since it's probably the most relevant. However, that was the only thing in the close proximity that came close to what was typed in, so we broaden our search a bit finding some possible matches.

One thing to note is that there are two user interaction models for the spell-checking component of this smart tag. The first is to correct misspellings for names the user already knew about. The second is to help youexplore the system. i.e. if you're interested in XPath but they don’t know if we have any support for it. So you type XPath and immediately see a wealth of information. Yourealize we have a whole namespace dedicated to this which they can then “use” and explore using the rest of the in-code intellisense architecture. 

I was thinking that because there are these two modes it might make sense to split the smart tag into two different things (see paragraph below). However it kind of makes sense here if you think of this smart tag as a method of resolving unknown names right at one central location. So rather than having to navigate away to add a using, or having to open object browser to find the right type, we offer the support right in the code and we offer support that no other tool in VS can give (i.e. finding names similar but not exactly like what you typed).

Something else I’ve considered is implementing this more akin to how Word does it with squiggles. i.e. type a name we don’t recognize and we underline it. If you right click then we offer the results right there in the completion set. However, I didn’t implement it this way because I already had the work done for this smart tag and I wanted to make this spike as light as possible.

What do you think?