Browsing vs. Typing

Though I'm sure most everyone will be interested in my introduction (ever notice that it's hard to be sarcastic on the web?), I doubt I'll get a lot of feedback on it. So, I've decided to post a bit more today. One of the features that we continually get positive comments on is IntelliSense. More specifically, virtually every user that we talk to likes completion lists. Interestingly, when asked about it most users say that they like IntelliSense because it helps them type. However, when we do user visits (a visit where we go and watch someone use Visual Studio instead of just asking them about it) we often see that a lot of folks use IntelliSense to browse as well as to type. Of course it's completely reasonable to say that figuring out what to type is as important as the act of typing; actually, I'd argue it's significantly more important.

Regardless, it turns out that these are conflicting interests given our completion list model. Currently completion lists must contain all possible valid entries that may be typed. If it didn't then you can imagine:

  • Users who are learning the language or framework getting confused on why what they see in a sample isn't available in completion lists

  • The annoyance of having the editor accidentally insert code you didn't want. This can happen if what you're typing isn't in the completion list, but a proper syntactic subset of it is

The second bullet is a little hard to grasp without an example. Imagine:

class Program
public void StartDelayed(int delay) { }

static void Main()
Program p = new Program();
p.Start // cursor here


Suppose that you're trying to call a method that you haven't yet declared called Start. In any version of VS when you hit an open parenthesis and the completion list is up (it will come up initially when the dot after p is typed) then it will complete on StartDelayed, because Start is a proper syntactic subset of something that is in the list. The more items that aren't in the completion list, the more pronounced this becomes.

Of course, if the focus of IntelliSense was on browsing as opposed to typing then it's clear you would want the list to be as small as possible. Windows Forms are a good example of this. Most of the time a quick way to find the controls that you've dragged onto the form would be nice, but the completion lists don't help because they contain so many members.

In certain cases, the issue mentioned above doesn't apply. For example, if you're catching an exception then the only valid items to put in the completion list after the open parenthesis of the catch are those types that derive from Exception (or contain a nested type which derives from Exception). This type of filtering is done in Whidbey for exceptions, bases and interfaces, attributes, etc.

We'll definitely be doing more with filtering in the future. You can probably imagine a huge number of options on how to filter, and I'd love to hear feedback if you think one would be particularly useful. Here are some ideas that we have considered:

  • Filter based on kind. Allow filtering down to only properties, only fields, etc.

  • Filter based on when the member was introduced in the class hierarchy. For example, show only those members which were introduced in the current type first, then the next filter level shows a mix of those and the members that were introduced in base classes.

  • Filter based on what's been typed so far. For example, if you have already typed 'a' then only those items that start with a would be shown.

  • Filter based on security. That is, if you are requesting a particular set of permissions then only show those members which could be called in that security context.

Outside of filtering, there is also the idea of organization within the completion list. For example, the completion lists could be organized such that the members that are most commonly used are at the top. This interacts well with filtering based on what's been typed so far. In order to get the user model for filtering correct, we'll probably need to give it a lot of time to gel. It will most likely be derived from a mechanism that will allow 'escaping' out to broader contexts; for example, if something isn't currently in the list but is available without filtering being applied is typed, then the completion list would grow to include the entire context.

I am curious to hear opinions about whether you use IntelliSense more for browsing or more for typing. If more developers use it for typing, then we’d probably set our default such that the list can be filtered, but is unfiltered by default. If more developers use it for browsing, then we’d likely set it to be filtered by default.