One thing i love when i see a feature suggestions comes in is when the person provides a lot of information as to why that feature would be beneficial to them. Rather than just leaving it as “improves development time” they take the time to really explain why it would be better than the current behavior and they’re willing to have a discourse over it. This came up recently when JavaKid posted this suggestion to ladybug. Now, after a long conversation with another C# user on the productfeedback site, JavaKid decided to consolidate all the information into a very interesting blog post. He talks about how the current intellisense model is failing him in two ways through a running example in both VS and Eclipse where he shows Eclipse to be a far easier and more productive environment to accomplish a certain task.. The first is that it doesn’t provide the simple tools he expects to help him with a lot of the boiler-plate code he doesn’t want to waste his time writing manually. The second is that our UI is often cluttered and present too much information to the user.
He’s right on both counts.
In order to help with writing boilerplate code we’ve expanded on some of the simple VS2003 features we had before (like implement interface and “+=” event hookup) to also include the “add-using” smart tag and the “generate method stub” smart tag. Both are intended to help you take the code that you’ve just typed and make it compile without having to force you to navigate elsewhere in the current file (or worse, another file). This allows you to stay “code focused” on the current task at hand.
IMO, eclipse is much better at this then we are. For example, if you paste in a block of code then they will incrementally compile it and offer many ways to fix up the code so that it will compile (i.e. add imports, generate method stub, create new class, etc.). Whereas we only offer support for what’s currently under your cursor. However, the smart tags are still an improvement from before, so hopefully it won’t be as bad an experience as before when he uses the IDE.
So that addresses the first problem, but what about the second? JavaKid shows how completion lists in the C# ide can overload you with information since they can contain many thousands of members in them. For him, the answer is simple. Just filter down the list as you type. It’s seems like a great idea, but it actually has a problem that I informed him of. Our usability studies have shown that people generally use intellisense in a few ways. The first is to just speed up typing by presenting to you what we know is valid to type. So, with just a few keystrokes you can type vast swaths of text easily and efficiently. However, the second is to use intellisense to actually browse the system to find out what is available. When you start filtering the list down you make this very difficult for users because then they have to delete what they’ve typed so far just to see all that is available.
We might hurt some users with a behavior so we don’t even offer it at all. Well to me that sounds like a cop-out. We should be able to serve the needs of both types of developers. So I sat down and spent an hour implementing a model which I think might do. I wanted to present it to you and my peers so that we could decide if it was the right way to proceed on this. It was surprisingly easy and the result (IMO) is extraordinarily nice to use. Currently it’s disabled by a registry switch, but when you enable it you get the following behavior in C#:
By default the list is in “all” mode, which corresponds to the standard non-filtered completion lists we have today. However if you move to “common” then we will filter the list down to items that match what you’ve typed so far. I’ll go through step by step.
As you can see, when the user types more and more of the word “List” the completion set filters down appropriately to only those things that contain “List” in them. If you type something not in the list we simply maintain whatever the current list is. And, as usual, we don’t care about casing when doing this. (That might lead to some interesting things like if you have an item like “zulIsTerrifying”, but I think that that’s an extreme corner case that really won’t screw anything up.)
The reason I went with a substring based match as opposed to a prefix based one was that I felt that it was very handing for browsing, especially when you could remember some part but not the entire name. For example, if you type “Exception” then you’ll see:
Ta-da: easy access to all the exceptions so that you can peruse them easily.
Now, you’re probably asking yourself “why on earth did he go with the two-tab model instead of just always filtering the list?” Well, I believe that there are certain times when filtering is very undesirable and that a user might want to turn it off. For example, a user might want to know what methods are available on Console, so they go to an existing invocation and they try to bring up a completion list a-la:
If they cannot disable the filtering easily then they won’t be able to see this very helpful view:
(Alternatively, we could go with an implementation that pays attention to where the cursor is and only shows things that match the substring *before* the cursor. However, I liked this behavior and how it made it very obvious to the user that there were two different modes they could choose from)
By default completion lists remember the last state they were in when they were opened. So if you’ll only switch from “common” to “all” if you explicitly invoke it with <ctrl><dot> Or <ctrl><comma>. This way users aren’t pulling their hair out asking “guh! Why is it in filtered mode again!?!”
Also, I really dislike the name “common” and if you can think up with something better let me know. “Filtered” seem to be appropriate, but I’m not if it would be explanatory enough.
If you like this and think we should includes options to enable this behavior, let me know. If you hate it and think it’s a bad idea, let me know. If you’re “meh” on it, still let me know and tell me if there’s something else you’d prefer with completion sets to help you out.