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.


Comments (19)

  1. dal says:

    Hi Anson, welcome to the web.

    I use Intellisense (IS) for both browsing and typing completion, and I’d expect this to be typical; it really depends on what I’m trying to do at the time, and a lot depends on how well I already know the object that I am dealing with.

    Because I do use the two modes, often back-to-back, I’d like some way to turn filtering on/off while I have the list up on the screen so I can easily see the effects of making a change. Perhaps a right-mouse click on the listbox to bring up a list of filtering options.

    How about the ability to resize the listbox? Sometimes the entire word is not visible.

    Here’s a few others:

    1. Filter based on namespaces only. This would reduce the number of items when at a toplevel point in the hierarchy.

    2. In the example you show the method Start has not yet been implemented. Add an option to have the Tab button auto-insert a stub method if the method name has not yet been defined in the object referred to. So in your exmaple it would insert a method called Start with no parameters and a void return type. The user would have to manually change it, so have an option that would take the user directly to the inserted stub method.

    3. How are you going to determine which exceptions to show? Same for security permissions.

    4. Please provide some "best practices" we can use to get the most of of these new features. Example: how much or little needs to be added to the xml doc tags for exceptions, security, etc.

    5. If these new features depend on the XML tags that are used to document methods, properties, etc., then modify the code generation wizards to provide default documentation for all wizard generated code.

    6. Use Intellisense in the xml doc area. There’s already a list of available tags, but the list is not complete, and when adding a cref it would be nice if it provided a list of items for those. e.g. if typing…

    <exception cref="System."

    I’d like to get intellisense on items following the word System.

    7. Remember the last item I selected, so if none of the rules used to find an initial item are not met the default is to take me back to the last word I was on if it is valid. Make the last selection "sticky".

    Thanks,

  2. David Cumps says:

    When starting with a new langauge I use IntelliSense for learning as well. As in "could you to this?", type the . and go looking if there is something that could do what I want.

    It proved to be a very good way for me to learn. And when you start knowing the language, it’s very nice to remember the start charachters of the method you want and then see it in IntelliSense and just pick it.

    "IntelliSense Learning" 😉

  3. Joku says:

    Hopefully it’s not too much asked if there is somewhere nearby a possibility to toggle/select between the ‘modes’.

    Some implementations of the ‘commonly used in top’ have been a bit annoying, but lets wait and see what you come up with 🙂

  4. At the least, I’d like it if it wouldn’t hit that second bullet-point twice – that is, if it inserts StartDelayed() once, and I correct it to be be Start() – then it shouldn’t automatically insert StartDelayed() the next time I type Start.

  5. It might be nice to have some filter options as tabs across the top of the intellisense box. Then I could hit the right and left arrow keys to select different tabs, and select the down arrow key to select different members.

    The default tab could display members that are most likely to fit based on some of the rules you mentioned to speed typing.

  6. anon says:

    "(Haacked)" above has exactly my idea, but better worded 🙂

    It would be great to have that.

  7. Ryan Gregg says:

    I pretty much use IntelliSense for all sorts of things, I’ve used it to discover new members or classes, to type out long names for me, and to browse for the method I’m looking for. I really like the concept that Haacked presents with some additional functionality on the window to provide the ability to move between sets of data, but at the same time I think it could confuse developers not used to the change.

    Additionally, and hopefully this isn’t too far off your filtering topic, but I’d love to see IntelliSense support enumerations without having to type out the enum name. Right now in C# when I’m working with an SqlParameter, I have to type SqlDbType. before I get the IntelliSense window. Since the paramter is defined as that particular enumeration, I would think it could display the IntelliSense window immediately, similar to how it works with a boolean variable in VB.NET.

    I look forward to future posts from your blog as well!

  8. Sean Terry says:

    I use IntelliSense for both as well, and I would echo dal’s comment that it would be nice to have IntelliSense work in the doucmentation cref’s as well.

    The only other change I would make is on the tooltips. When you hover over a member, a tooltip appears and gives you a little info on the member. I would like it if, after another brief period of hovering, the tooltip expand to show all the overloads.

  9. I actually use IntelliSense more for typing. browsing or more for typing. For example, if I start typing:

    When I hit the . before "sql" I get IntelliSense that goes right to "SqlClient" and I can just hit TAB and I get "System.Data.SqlClient

    " which is what I want.

    Furthermore I can hit CTRL+SPACEBAR at any point to help me complete my statement. This is great, especially in being able to overcome the case-sensitivity of the C# language.

    Now, please…Make Edit-and-Continue happen! 🙂

  10. I’ve reached a zen-like state of one-ness with intellisense as it exists in vs.net, to such an extent that I can actually produce code efficiently using the text input panel on my tablet… ("sy" dot tab "co" dot tab "w" dot paren ctrl + v…)

    I know of some of the code completion stuff thats coming in whidbey, and it looks great… there are, though, some really simple home-run type things that could really increase usability for both typing and browsing behaviors.

    1.) How about making the drop down semi-transparent?

    2.) How about a real time preview of the result of the evaluation of a format string? i.e., i type ("{0} was here on {1}!"’, and then as i type ‘,contact.Name’ and ‘,contact.VisitDate’, i get a tooltip that displays ‘[name] was here on 1/15/1993’?

    3.) I always thought that some work could be done in terms of pre-selecting methods based on context… for example, if I type ‘DateTime dt = myObject.’, couldn’t you sort the list such that the methods that return objects of type DateTime?

    4.) there are some methods/constructors that have a large number of overloads… which leads to a tooltip/spinner with a large number of steps, and only one visible at a time. seems to me that in these cases, a drop down would be more appropriate? or maybe even a tree like structure?

  11. Adam says:
    • I use intellisense for both typing and browsing, however I use it for word completion more than anything else.

      * I really dislike VS changing around the intellisense list. The first thing I did in VS2k3 was turn off that horrible feature that autoselected frequently used members. It screwed me up more than helped me, so I turned it off.

      * I don’t think I would mind filtering based on context, however I don’t think I would use it. My typical typing goes as follows:

      S CTRL+SPACE . D . S . SqlCo ENTER and gives me:

      System.Data.SqlClient.SqlConnection.

      * What I think that is more important than changing the way current Intellisense works is to finish it on needed features, such as base constructors:

      public MyClass() : base( //NO INTELLISENSE!!!

      * Finally, whatever you do to Intellisense, do not make it require the mouse. Out of all the developers I’ve worked with, I’ve only seen one who ever frequently used the mouse on the Intellisense list.

  12. Andrew Deren says:

    Filter by class hierarchy would be great. Lots of times for user defined controls typing this. gives huge list, but all I want is list from my class.

    Default selection should show all, but as someone suggested having tabs to navigate would be great to switch to "my defined members".

    All intelisense navigation should have keyboard shortcut so that I don’t have to use mouse to change filter or something else.

  13. Joku says:

    http://blogs.msdn.com/vseditor/archive/2004/06/14/155589.aspx

    I wrote my thought there about this as this blog seem a bit inactive.

  14. lena says:

    nu duxai grynai kaip dima

Skip to main content