Filtering as you type


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)

 

Other things:

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.


Comments (51)

  1. AT says:

    This is just a FYI:

    Original JavaKid report:

    http://lab.msdn.microsoft.com/ProductFeedback/viewFeedback.aspx?FeedbackId=FDBK17461

    And his blog posting

    http://javakid.blogspot.com/2004/11/visual-studio-making-intellisense.html

    I’ve expressed my opinion once at Product Feedback and at prior Cyrus postings.

    Quote from Product Feedback: "Microsoft can do this by changing current simple dropdown list to some more complex dialog with filters/search/options."

    Overall I think that Intellisense then used for typing ARE different from Intellisense then searching for some sutable class. Filtering everything that has List word – are most-likely search for class name you do not know before.

    If wish to assist with class search – you must focus on different problem.

    Current Intellisense dropdown list provide only tiny class help information (summary section content only). For a newbie who search for most-sutable class there must be easy way to access MSDN documentation.

    Something like "Click here for more details" of hotkey that will show MSDN documentation without quiting from edit window.

    http://www.24.odessa.ua/PF/XMLParamHelp.png (I’ve proposed as http://lab.msdn.microsoft.com/ProductFeedback/viewfeedback.aspx?feedbackid=FDBK14030 )

    I think this is more important than different filtering for class names. This must be added value – not a change to existing functionality. This must teach newbies to code according to documentation – not method/class names.

    From my limited expirience with usability research – regular users sometimes were able to remember a long list of NUMERIC inventory codes and this way increase data-entry speed in factor of magnitude. As well they very often able to remember shortest character sequences that allow to select requered item. Here JavaKid suggestion to show all items a-la Eclipse can be valuable – this sequence must not be different based on "using" statements used. I agree. But this can be workarounded easility if new class template will provide most common using statements.

    But in the same way – I dislike that Eclipse dynamicaly filter items – this is somethat uncommon functionality not known to users before. Take a look on Microsoft Access or any other dropdown lists – they do not filter out items – they simply show all items and nagivate to best item – instead of filtering.

    In summary 😉

    I’m still willing Google search box integrated in Intellisense drop-down list and classes/methods proposed were based on free-text query results from MSDN/Internet webpages.

    This must allow newbie to find best class easily and spammers to promote "new CheapViagra.call(‘+1 800 1234678’)" methods 😉

  2. Luc Cluitmans says:

    This looks cool!

    However, in the "WriteLine" screenshot, I would definitely vote for using only the part of the word *before* the cursor as a key for the completion list – that would allow leaving the mode in ‘Common’ most of the time, and switch to ‘All’ only when using intellisense in a browsing style. Your choice of ‘WriteLine’ in this example is brilliant btw. – thats precisely the word that I quite occasionally have to change to ‘Write’.

    Using substrings for matching is a quite interesting approach. It might help tremendously with thoses cases where a huge amount of matches with the same prefix exist, though some testing may be required (anyone else dreading the moment they have to type ‘XmlNodeType.Element’ ?)

  3. How about "Matching" instead of "Common"? That makes it clearer that you’re talking about the list of items that match what you’ve typed. "Common" suggests it’s a list of the most commonly used items, which it isn’t…

    Another intellisense gripe (that actually came up in someone’s blog before but I forget whose) is that intellisense shows inherited static members. I can’t think of a single case where you’d ever want to call, say, object.Equals through any class other than object (the meaning would be very confusing), but those names still show up in intellisense. Have you thought about removing these?

  4. Duncan says:

    How long can a response be? Guess we will find out 😉

    OK – I like it and I don’t. Intelli-sense is awesome (possibly too awesome – it becomes an addiction), but it is regularly annoying.

    The fact that it shows the whole list by default is indeed an issue and filtering it by name is a great start. But it is no IMHO the whole issue.

    The bigger issue is that intellisense should be showing context information that is valid, not stuff that isn’t. But it should also be giving sugestions that are automatically culled from code and or documentation.

    What do I mean by this?

    If I type

    ‘new Ar’

    then there are quite a few clues I have already given inteli-sense about my intentions.

    I’ve typed ‘new’ therefore I am constructing an object, so don’t show me variables, or interfaces, or abstract types – clearly I can’t use them.

    I’ve typed ‘Ar’ therefore I am probably looking for a class that begins with (or at least contains) the letters Ar, your filtering is a good start for this, but you should also sort the list by the most likely matches assuming I know what I am doing. So you should first list Array, ArrayList, etc and then other classes that happen to include the letters Ar, again sorted – so the fact that I typed a capital ‘A’ is significant – always assume I know what I’m doing and offer those options first, but be aware that I may be a bit forgetfull so offer other options but further down the list.

    In the same way the intelli-sense should first look at my existing code at the local scope, then the class scope, namespace scope, project scope, solution scope. The locality of the found information should be used in sorting the returned results. Eventualy when you have looked through all of the code in the referenced frame you should look through system libraries, and any user specified paths, for more possible matches. These should also be presented, but indicated clearly that they need additional work.

    So lets assume that I hadn’t imported System.Collections.

    The intelli-sense list should indicate that ArrayList is a good match but isn’t currently imported (maybe not even referenced by the project yet). If I select it in the list then you can do one of two things – import it fully qualified (adding a project reference if needed) or add the appropriate using statement. There is no way you can guess ahead of time what the user would prefer so you should offer both. How? I would sugest by a second stage collapsing inteli-sense.

    Eh? Ok, you select ‘ArrayList’ from the inteli-sense menu. The word ‘ArrayList’ gets inserted into your code and new inteli-sense menu automatically pops up with two options ‘Fully Qualify Name’ and ‘Add using System.Collections’. The user can then quickly select the option they prefer and remain code focused on the current problem.

    Next, if we are doing a ‘new’ then we know that the user will need a ‘(‘ next, so why not insert it straight away? If the only constructor is a default constructor then wy not also insert the ‘)’ ?

    Other situations where intelli-sene should work but doesn’t is in things like access specifiers. If I’m at the class scope and I type ‘pro’ then why don’t I get the opportunity to auto-complete ‘protected’ ? The same goes for ‘override’ ‘private’ ‘public’ ‘class’ ‘interface’ ‘abstract’ etc. In almost all these cases the context of where we are typing means that there are only a very limited number of choices available – so why doesn’t intelli-sense help me out?

    Intelli-help? Currently when a item is selected in the intelli-sense a tooltip shows up giving return type, fully qualified name, and help. But where is the list of overloads? That’s right you have to accept the sugestion before you can check – it would be much nicer if a list of overloads where shown in the tooltip.

    Anyway, getting back to the filtering point:

    Not only can you sort the list, but you have two distinct groupings that you can use, above and below the selected item. Maybe you could place elements that are in reference on and below the current item as the user is typing, and those which would require additional usings or references above the current item. (Obviously items above the selected item would be sorted the other way so that the bets match always takes the least key presses).

    Filtering should be based on characters to the left (in english speaking countries) of the caret. Thus moving the caret left (or deleteing left) will expand the scope of the search, moving it all the way to the . (or intelli-sense trigger point) will then show the full list. The use of tabs on the popup menu is not wise since normal intelli-sense use is keyboard based (from what I’ve seen) not mouse based.

    Your point about users typing xml and looking for interest around that is well taken, however your idea of ‘instring’ filtering makes good allowance for that. Always providing the full list is ok for short lists, but when they get long it is very easy to scroll right by the item of interest without even seeing it, at that time filtering would make this ‘api searching’ easier not harder.

    So, that’s a few initial thoughts, if you have interest in discussing anything further then contact me by e-mail (dgkimpton [at] iee org).

    It’s good to know your thinking about this stuff.

    Thanks

    Duncan

  5. I like it and I think the term "Filtered" is better than "Common". The substring search seem to be very useful, but maybe it should be used in the "All" mode only. This way the "all" mode would be more like a "browsing" mode where the "common" mode would be a completion list to speed up typing.

  6. Stuart: "How about "Matching" instead of "Common"? That makes it clearer that you’re talking about the list of items that match what you’ve typed. "Common" suggests it’s a list of the most commonly used items, which it isn’t… "

    I like it 🙂

    "Another intellisense gripe (that actually came up in someone’s blog before but I forget whose) is that intellisense shows inherited static members. I can’t think of a single case where you’d ever want to call, say, object.Equals through any class other than object (the meaning would be very confusing), but those names still show up in intellisense. Have you thought about removing these?"

    A better question is "why does C# allow inherited access to static members?"

    We just try to follow the language and allow you to type what’s legal 🙂

    Of course, we filter them out in the enum case so it certainly seems reasonable to do it for all types. I’ll bring it up tomorrow.

  7. Luc: Thanks for the feedback. however, could you help explain this a little bit more:

    "Using substrings for matching is a quite interesting approach. It might help tremendously with thoses cases where a huge amount of matches with the same prefix exist, though some testing may be required (anyone else dreading the moment they have to type ‘XmlNodeType.Element’ ?)"

    I’m not sure what you mean. Why would this be difficult?

    (i’m not at work, but i’ll try it tomorrow to see what it’s like)

  8. Duncan: Thanks for the awesome feedback. I’m guessing you haven’t used VS2005 yet. hopefully you’ll get a chance to and you’ll like what we’ve done.

    —————

    "How long can a response be? Guess we will find out 😉

    OK – I like it and I don’t. Intelli-sense is awesome (possibly too awesome – it becomes an addiction), but it is regularly annoying."

    Any time something annoys you, let us know! 🙂

    —————

    "The fact that it shows the whole list by default is indeed an issue and filtering it by name is a great start. But it is no IMHO the whole issue.

    The bigger issue is that intellisense should be showing context information that is valid, not stuff that isn’t. But it should also be giving sugestions that are automatically culled from code and or documentation.

    What do I mean by this?

    If I type

    ‘new Ar’

    then there are quite a few clues I have already given inteli-sense about my intentions.

    I’ve typed ‘new’ therefore I am constructing an object, so don’t show me variables, or interfaces, or abstract types – clearly I can’t use them. "

    In VS2005 we do do this. The important thing to realize is that interfaces and abstract types *are* acceptable. Why? Because you could type:

    new IList[]

    and if we don’t show you IList in the list then we will screw you 🙂

    in VS2005 we filter to the list to types only though.

    There are other cases where we will help out. For example of you type "catch(" then we filter down to only exception types. If you type "[" then we filter down to only attributes. After an "as" we filter down to only reference types. After "event" we filter down to delegate types. I hope that that helps!

    —————

    "I’ve typed ‘Ar’ therefore I am probably looking for a class that begins with (or at least contains) the letters Ar, your filtering is a good start for this, but you should also sort the list by the most likely matches assuming I know what I am doing. So you should first list Array, ArrayList, etc and then other classes that happen to include the letters Ar, again sorted – so the fact that I typed a capital ‘A’ is significant – always assume I know what I’m doing and offer those options first, but be aware that I may be a bit forgetfull so offer other options but further down the list. "

    Sorting is dangerous, since it affects how items are selected as you type. Of course, if we are filtering as you type then the effect is mitigated (i think)

    —————

    "In the same way the intelli-sense should first look at my existing code at the local scope, then the class scope, namespace scope, project scope, solution scope. The locality of the found information should be used in sorting the returned results. Eventualy when you have looked through all of the code in the referenced frame you should look through system libraries, and any user specified paths, for more possible matches. These should also be presented, but indicated clearly that they need additional work.

    So lets assume that I hadn’t imported System.Collections.

    The intelli-sense list should indicate that ArrayList is a good match but isn’t currently imported (maybe not even referenced by the project yet). If I select it in the list then you can do one of two things – import it fully qualified (adding a project reference if needed) or add the appropriate using statement. There is no way you can guess ahead of time what the user would prefer so you should offer both. How? I would sugest by a second stage collapsing inteli-sense. "

    ‘m not sure how we’re goign to know about types that aren’t even referenced in your project. we’d have to be omniscient to be able to do that 🙂

    Now, as for types that are in your project we could do something like inserting them in the list (possibly italicized to indicate they aren’t available).

    ———————-

    "Eh? Ok, you select ‘ArrayList’ from the inteli-sense menu. The word ‘ArrayList’ gets inserted into your code and new inteli-sense menu automatically pops up with two options ‘Fully Qualify Name’ and ‘Add using System.Collections’. The user can then quickly select the option they prefer and remain code focused on the current problem. "

    That’s how it works today. After typing in the type name we’ll offer the ways to do the grunt work for you.

    ———————-

    "Next, if we are doing a ‘new’ then we know that the user will need a ‘(‘ next, so why not insert it straight away? If the only constructor is a default constructor then wy not also insert the ‘)’ ? "

    One of the reasons is because you might be doing something like:

    new Foo.Bar()

    (where Bar is a nested type).

    So we could "not" add the parenthesis if the type has a nested type in it, but then the experience is very confusing for users. People will be asking "how come i get parenthesis automatically in some cases, but not others?"

    —————————

    "Other situations where intelli-sene should work but doesn’t is in things like access specifiers. If I’m at the class scope and I type ‘pro’ then why don’t I get the opportunity to auto-complete ‘protected’ ? The same goes for ‘override’ ‘private’ ‘public’ ‘class’ ‘interface’ ‘abstract’ etc. In almost all these cases the context of where we are typing means that there are only a very limited number of choices available – so why doesn’t intelli-sense help me out? "

    It does in VS2005 🙂

    Keywords are available in completion lists and are contextually filtered appropriately (i.e. the "this" keyword isn’t available in static methods).

    ————————

    "Intelli-help? Currently when a item is selected in the intelli-sense a tooltip shows up giving return type, fully qualified name, and help. But where is the list of overloads? That’s right you have to accept the sugestion before you can check – it would be much nicer if a list of overloads where shown in the tooltip. "

    i’ll try adding an option to make that happen. The major issue is that it can end up taking an excessive amount of space to show this information. Take Console.WriteLine (+ 18 overloads). It gets very dense and cluttered very quickly. But we can try it out.

  9. Steve says:

    Why not do both in the menu, filtered items near the top, probably limited to the best 10 matches and the reference list below?

    I think the way the menu would filter as you type would make it obvious that deleteing characters would take it back the other way – I don’t think users will have a problem with it.

    S.

  10. Duncan says:

    Duncan: Thanks for the awesome feedback. I’m guessing you haven’t used VS2005 yet. hopefully you’ll get a chance to and you’ll like what we’ve done.

    >>

    Nope not yet – the company policy is only to use released products and there is no way I can afford to buy an MSDN sub for home 🙁

    From below it sounds like I’m going to like what you have done though 🙂

    —————

    Any time something annoys you, let us know! 🙂

    >>

    Heh – but it’s a question of where to post it. I mean mostly things arn’t bugs, they’re not really feature requests, mostly it’s just gripes, grumbles, and ideas. Where do you post things like that? I’m sure I don’t know. I’m only posting here thanks to the link in your tribus.

    —————

    The important thing to realize is that interfaces and abstract types *are* acceptable. Why? Because you could type:

    new IList[]

    and if we don’t show you IList in the list then we will screw you 🙂

    >>

    Hmm, I think I need to think about that more, but surely the only valid place to type that would by in array cases? Thus in normal cases you could filter them out. I’m not sure though, and you’ve probably given it more thought than I 😉

    —————

    in VS2005 we filter to the list to types only though.

    There are other cases where we will help out. For example of you type "catch(" then we filter down to only exception types. If you type "[" then we filter down to only attributes. After an "as" we filter down to only reference types. After "event" we filter down to delegate types. I hope that that helps!

    >>

    This sounds excellent – I can’t wait.

    On a releated note it would be even nicer if the catch could filter down to just the events that code included inside the current try could actually throw. Of course that is also a lot of work so it might be nice just to have a function that could be called to provide that kind of information.

    ####

    Going off on a tangent a bit it would be very nice if the IDE could determine the events that every method could throw and then listing them after the function declaration (perhaps in light grey uneditable text).

    i.e. public void DoSomething(…) canthrow ArgumentException, IOException {

    // TODO: Write file handling method

    }

    this would be determined by parsing down the source code and actually seeing what gets thrown, not by asking the coder to type this in (as we saw in Java specified exception lists are a bad thing).

    Of course I realise this has issues when working with dll’s, com controls, etc but it’s a nice fuzzy pipe dream.

    ####

    —————

    Sorting is dangerous, since it affects how items are selected as you type. Of course, if we are filtering as you type then the effect is mitigated (i think)

    >>

    Whilst that is true, if you are sorting correctly then the match should always be getting better so the issues would be less annoying.

    —————

    I’m not sure how we’re goign to know about types that aren’t even referenced in your project. we’d have to be omniscient to be able to do that 🙂

    >>

    Basically you could look through the standard .Net framework and allow the user to specify (for VS in general, not per project) other places to look for code. It might be a bit of a heavy parsing problem – but it would be nice…

    —————

    Now, as for types that are in your project we could do something like inserting them in the list (possibly italicized to indicate they aren’t available).

    >>

    That would be a good start IMHO.

    ———————-

    "Eh? Ok, you select ‘ArrayList’ from the inteli-sense menu. The word ‘ArrayList’ gets inserted into your code and new inteli-sense menu automatically pops up with two options ‘Fully Qualify Name’ and ‘Add using System.Collections’. The user can then quickly select the option they prefer and remain code focused on the current problem. "

    That’s how it works today. After typing in the type name we’ll offer the ways to do the grunt work for you.

    >>

    That sounds fantastic. Nice one.

    ———————-

    new Foo.Bar()

    (where Bar is a nested type).

    So we could "not" add the parenthesis if the type has a nested type in it, but then the experience is very confusing for users. People will be asking "how come i get parenthesis automatically in some cases, but not others?"

    >>

    OK – didn’t think of that. Never mind then.

    —————————

    It does in VS2005 🙂

    Keywords are available in completion lists and are contextually filtered appropriately (i.e. the "this" keyword isn’t available in static methods).

    >>

    Why am I not using VS05 again? Drool.

    ————————

    "Intelli-help? Currently when a item is selected in the intelli-sense a tooltip shows up giving return type, fully qualified name, and help. But where is the list of overloads? That’s right you have to accept the sugestion before you can check – it would be much nicer if a list of overloads where shown in the tooltip. "

    i’ll try adding an option to make that happen. The major issue is that it can end up taking an excessive amount of space to show this information. Take Console.WriteLine (+ 18 overloads). It gets very dense and cluttered very quickly. But we can try it out.

    >>

    That’s true, but even a scrollable box would be nice – just something that makes it possible to check without having to loose the current point in the workflow.

    Thanks for taking the time to respond

    D.

  11. DrPizza says:

    It’s funny.

    I hate Eclipse’s behaviour when I’m at work.

    I hate VS.NET’s behaviour when I’m at home.

  12. DrPizza says:

    I *do* however like the ability to use unimported types in Eclipse and then hit ctrl-shift-m to add the import statements. VS.NET needs that.

  13. Jim Argeropoulos says:

    I like the proposal.

    What about "Contains" for a tab name?

  14. AT says:

    Duncan:

    "Intelli-help? … That’s true, but even a scrollable box would be nice – just something that makes it possible to check without having to loose the current point in the workflow. "

    You are thinking exactly in the same way as me 😉

    http://www.24.odessa.ua/PF/ParamHelp.png

    http://lab.msdn.microsoft.com/ProductFeedback/viewfeedback.aspx?feedbackid=FDBK13708

  15. John S. says:

    You should call it IntelliMatch or IntelliCode

  16. Very cool Cyrus. Let us know when it’s available to play around with (or is it in Beta1 / October CTP? If so, which key?).

    Someone mentioned showing items that aren’t imported/referenced. I like the current way of dealing with it. If every possible item was shown, regardless of the using statements or references, the list would be totally cluttered.

  17. JavaKid says:

    Cyrus,

    What can I say? Not only are you actively parctipating and listening to the development community but you are making strides within Microsoft on our behalf, kudos to YOU!

    I think you’re absolutely on the right track. You are taking both sides of the story into consideration and creating a "best of both worlds" solution.

    Duncan and all others who have ideas, Cyrus and others at Microsoft are doing a fantastic job of listening and reading the MSDN Suggestion Box… enter all of your ideas for everyone to see here:

    http://lab.msdn.microsoft.com/productfeedback/

    and make sure to actively vote on the items that are important you!

    JavaKid

  18. Brett says:

    Bravo!!! I haven’t read all the comments yet, but overall I am absolutely digging the direction you are going in!

  19. Sean Chase says:

    Personally, I’m pretty content with "ALL", I’m used to it, I work with it all day long, it’s great. I like the idea of the tabs with "Common" and "ALL". Until I work with VS2005 on a daily basis, I’m not sure which I’d use more. My feeling is that at the very least, please don’t take away the behavior I’m used to right now, but I’m happy to check out new features. The ability to toggle back and forth sounds very cool to me. After a few months, I’d have a better "usability study" for you. Until then, this is about the best feedback I can give you.

  20. Haacked says:

    I love it! How do you switch between tabs? I vote for right and left arrow keys.

  21. Great ideas everyone, I love seeing this process in action. I’ll add my 2 cents:

    I don’t like the idea of sorting the list by "most likely" – I just don’t trust the computer to always know what I’m going to write (if it did, I would be unnecessary). And if the computer doesn’t guess right, it will make it HARDER for me to find what I was looking for – how would I know if the computer rated my item as unlikely, so I have to look at the bottom of the list? The list should only be sorted alphabetically, as that is the only way to predictably find the data I am looking for.

    Also, if you are going to show "ALL" items, I think there should be a graphical indication for the classes that are not imported — maybe they are greyed out, or have a grey background, etc. That should help you visually filter out the items you know you don’t care about (assuming you know the item you are looking for has already been imported).

  22. Dr.Pizza: What sucks and what can we do to help? 🙂

  23. Michael: No it isn’t. I literally code it up last night 🙂

    I hope it’ll be in beta2

  24. Haacked: " I love it! How do you switch between tabs? I vote for right and left arrow keys."

    It’s configurable. You can bind it to anything. By default it’s

    ctrl-dot and ctrl-comma, but we’ll probably change that.

  25. Duncan: A few more points:

    a) You can download the beta1 of the C# express sku for free, you don’t need an msdn subscription

    b) IList[] : yes, it’s only balid when you’re typing an array, however, it’s not always the case taht someone types:

    IList[] a = new …

    and we don’t want to screw up users from typing legal expressions.

    Note: we’ve tried this in the past and we often get very angry feedback from people who say "why is ‘Foo’ in the list??"

    c) "catching appropriate exceptions". This is a great idea and we have a very poor story here for 2k5. We want to make this a lot better in the future

    d) "scanning through the standard .net framework". Right now that’s a bad idea. People target projects at different versions of the frameworks and different versions of their own (and otehr dlls). Scanning through can lead to some very misleading information. I think it’s much better to just allow the user to adjust what dlls are in the project. Now, that said, the defaults for projects could include a few more dlls to make the chance of hitting the types you need more likely

    e) "That’s true, but even a scrollable box would be nice", Yes. i Agree. One of my problems is that i think about what’s possible in terms of the current technology available. Right now we don’t have scrollable tooltips, and gettng them would require substantial work from teh UI team. So i think about fitting in more information into the current tooltips (since that’s much cheaper), but it blinds me to obvious suggestions like that 🙂

  26. Sean: Here’s how the behavior would be:

    By default no filtering. That means taht you see the normal completion list and there are no tbs on it.

    If you turn on filtering then you get the completion list that has two tabs. The "all" tab works the same way as havnig no filtering and the "common" tab is the filtered one. This way you don’t have to go flip a switch in "tools | options" to get the behavior you want.

  27. Joahua (and everyone else): "The list should only be sorted alphabetically, as that is the only way to predictably find the data I am looking for. "

    ^^^^^^^^^^^^

    What he said is very very true. Usability shows that non sorted lists are extremely difficult for people to understand (generally because they are sorte just not in intuitive ways for the user). Alphabetical makes it understandable and makes the selection model sane.

    i.e. if you have a non sorted list and you’re typing then the "selected item" can jump around wildly all over the list which can be very disconcerting.

  28. Darren Oakey says:

    Cyrus – I like it,

    but

    I think it’s important that there’s some really really simple keyboard way of switching between the tabs (I like the left-right) key solution. When I’m writing code, I almost never take my hands off the keyboard.

    On a side note… recently, I’ve gone through a radical increase in productivity – I’ve started using coderush. The vast majority of it is an exercise in "how the hell do I turn this stupid thing off" – but hidden inside it has this one incredible gem – templates. It will watch what you type and use a configurable macro rule to replace what you type with something else. It’s now rare for me to type anything NOT templated. prop string[right]Blah gives me a private variable and an accessor. testblock gives me a new test class for the current class, in a region – newtest testname gives me an attributed test stub.. It’s brilliant – a whole new level of coding productivity.

  29. Sean Chase says:

    Cyrus that sounds perfectly reasonable and quite cool to me. One in a blue moon when I have to work in VB.NET, I have to UNCHECK "Hide Advanced Members" and that’s not exactly a hassle by any means. 🙂

  30. Uwe Keim says:

    Don’t make anymore suggestions here, all you other comment-writers. The less suggestions, the faster the product can be finished and the earlier it can be released 🙂

  31. Luc Cluitmans says:

    <Quote>

    " Luc: Thanks for the feedback. however, could you help explain this a little bit more:

    "Using substrings for matching is a quite interesting approach. It might help tremendously with thoses cases where a huge amount of matches with the same prefix exist, though some testing may be required (anyone else dreading the moment they have to type ‘XmlNodeType.Element’ ?)"

    I’m not sure what you mean. Why would this be difficult?

    (i’m not at work, but i’ll try it tomorrow to see what it’s like)"

    </Quote>

    My comment about ‘XmlNodeType.Element’ was about the fact that ‘XmlNodeType’ has many prefixes in common with other frequently used words (the ‘Element’ was just an example) . Well, at least there are many prefixes common with other words in the System.Xml namespace. Xml… is a prefix of very many words, XmlNode is a commonly used word. In short: to type XmlNodeType you at least have to type ‘XmlNodeT’ before you can invoke the completion. That doesn’t sound like a long word type, but it is a significantly longer prefix than most other system types. Usually typing two or three letters and hitting the completion key is enough, and this case is significantly longer…

    And, thinking about it again, maybe your suggestion of using substrings doesn’t help too much here, unless my mind can be wired to type ‘lNodeT’ when I really want ‘XmlNodeType’ 😛 . Obviously all of ‘Xml’, ‘Node’ and ‘Type’ are frequently occurring substrings.

  32. Luc. I think you’re mistaken.

    When you type "Xml"

    it will filter down the list to thing containing "xml" in them, but you wil be selecting teh first thing in the list that "starts with" xml. So it will take just as long to write XmlNodeType as it currently does.

    See the above picture. Just because "LinkedList" contains "list" it does not make typing "List" difficult.

  33. Luc Cluitmans says:

    <Quote>

    Luc. I think you’re mistaken.

    When you type "Xml"

    it will filter down the list to thing containing "xml" in them, but you wil be selecting teh first thing in the list that "starts with" xml. So it will take just as long to write XmlNodeType as it currently does.

    </Quote>

    Ah, a little misunderstanding. Yes it will take just as long as it does now – I never intended to say otherwise. But I was hoping for a way to type it *faster* than now…

  34. Luc Cluitmans says:

    About the Ctrl-. and Ctrl-, keys as shortcuts: this reminds of a gripe I had with some other standard keybindings (though in this case it actually is not a problem).

    The problem is that not all keyboards in this world are equal. I recently was trying to figure out what the shortcut for ‘match brace’ was, and found the documentation that said it was ‘Ctrl-[‘. Now, my keyboard doesn’t have a ‘[‘ key … The ‘[‘ is typed on my (finnish) keyboard as AltGr-8; keeping a CTRL key down simultaneously as a third key is a bit hard, and it doesn’t even work.

    SideNote: If you don’t know what ‘AltGr’ is: most european keyboards have a different left and right ALT key; the right ALT key (labeled AltGr) acts as a secondary shift key, which must be kept down to type the third symbol on a key – many keys correspond to three symbols, rather than only two symbols (with Shift or without Shift) on US keyboards.

    It took a short time to figure out what key to use instead for the ‘brace matching’ (and which command this actually was). It happened to be CTRL+the key that is in the same position as the [ key on a US keyboard: CTRL-Å.

    Now the moral of this story:

    when writing documentation about keybindings that involve other keys than letters or numbers: please realize that (western) keyboard layouts all have at least the 26 keys for the letters, the 10 keys for the numbers, a Shift, a Ctrl and an Alt key, but beyond that do not make any assumption on what keys are on a keyboard. When writing documentation involving other keys (such as ‘Ctrl-.’) make sure to document the name of the editor command that it corresponds to, so I can look up its true keybinding in the keyboard mapping dialog.

    Now that has been said, it doesn’t matter too much for me in this particular case: there are separate ‘.’ and ‘,’ keys on my keyboard 🙂

  35. Luc: We have an MRU stack kept for completion lists (contextually). So we’ll remember what the most recent namespace element you chose was, or the most recent type member, or the most recent local, etc. We’ll then preselect items in the list based on that.

    hopefully that will speed thigns up for you.

    It’s weird, sometimes the IDE seems a bit clairvoyant with its choices and it can end up being creepy. I keep expecting clippy to show up and say "it looks like you’re writing a client server app, do you want help with that?"

  36. Luc: We are very aware of the different keyboard issue. It’s completely sucktastic and it’s one of the reasons that we’re endin gup with key bindings like:

    ctrl – shift – x, ctrl – alt – y

    I added a MRU stack to the editor to help you with typing things that you’d just typed over again (i.e. you just typed something in a comment and now you want to use that exact word as a method name, or vice versa), and coming up with free keys to bind to cycle forward/backwards was near IMPOSSIBLE!

    *everything* on the keyboard is taken, and OOB there are already some conflicts because it is just impossible to map them all uniquely.

    Now, that said, a heck of a lot of work went in C# for 2k5 to make the keybindings sane and accessible from many keyboards, but i can’t guarantee that all keyboards will be ok (there are just too many combos). So you might have to do some customization. Sorry 🙁

  37. Luc Cluitmans says:

    <Quote>

    We have an MRU stack kept for completion lists (contextually). So we’ll remember what the most recent namespace element you chose was, or the most recent type member, or the most recent local, etc. We’ll then preselect items in the list based on that.

    </Quote>

    Yup, I’m aware of that. I guess that’s why "Console.W" wants to complete to ‘WriteLine’, rather than ‘Write’. Which at most times is perfectly ok, but makes typing ‘Write’ a minuscule tad harder.

    However, it doesn’t always seem to kick in (talking mostly about VS2003 now). At least, I have never seen ‘XmlNodeType’ or ‘XPathNavigator’ being preselected, though I use those often. Maybe just not often enough.

    <Quote>

    *everything* on the keyboard is taken, and OOB there are already some conflicts because it is just impossible to map them all uniquely.

    </Quote>

    Well, there’s still combinations like Ctrl-Å, Ctrl-Ö, Ctrl-Ä and Ctrl-§ – those are valid on my keyboard 🙂 But seriously, as I said, the number of keys that are guaranteedly available on all western keyboards is easily exhausted. And I guess that it is even worse when taking non-western keyboards into account.

    I guess we will have to reintroduce footpedals as standard PC equipment again, so we can type CTRl-ALT-LeftFootPedal-A 🙂

  38. Luc: yup, there were a lot of bugs with preselection in 2k3. I’ve been working on it recently so it should be a lot better now. If you get a chance to download beta2 when it comes out let me know if it’s better.

  39. Philip says:

    I remember using the Intelli* features in VB5, and really liked the non-intrusive way in which it exposed functionality (methods, properties, etc.)

    The discussions above just illustrate that VS2005 will push the envelope further.

    Great going!

  40. Keith Hill says:

    Re:

    >> Now, that said, a heck of a lot of work went in C# for 2k5 to make the

    >> keybindings sane and accessible

    I spent a fair amount of time submitting enhancements to the updated keyboard shortcuts and it was looking really good in B1. But then in B1 refresh and the October CTP drop, the new C# keyboard shortcuts disappeared and the old VS.NET 2003 shortcuts seemed to be in place. What’s up with that? I was looking forward to the new shortcuts. They were a helluva lot easier to remember.

  41. BMoscao says:

    I positively love this ideia, Cyrus!!

    "Matching" is a good name for the tab.

  42. Keith: I’m investigating the keyboard shortcuts thing. I’l try to get some info on this soon (unfortuantely all teh PMs are out today).

  43. Keith Hill says:

    Cyrus: Thanks. I know the proposed changes generated a *lot* of "input" from folks who have had to suffer through changes to kbd shortcuts in VS over the years. I thought the consensus was "OK we’ll give you one more shot but please get it right this time and stick with it". I’m a bit afraid though that the changes have been shot down because of the negative reaction by some. Too bad because I really dig chorded kbd shortcuts.

  44. DrPizza says:

    You have no business programming on a keyboard that’s not US or UK layout.

    Set up a hotkey to switch layouts between US/UK (your choice) and whatever your native layout is, and then use US/UK for programming.

    The simple fact is that programming is quite symbol-intensive (lots of braces, brackets and numbers), and non-English layouts are almost universally poor at handling those characters. You take up too much space with accented characters instead.

    In a related note, I wish Windows supported a proper "compose" key. It does support keyboard layouts with dead keys, but they’re not so convenient, as they require more fingers (a compose key can be struck independently of the pair of composed characters, whereas dead keys can’t), and are asymmetric (a compose key can typically (always?) accept the pair of composed characters in any order, whereas dead keys require me to create each ordering by hand, which is immensely error-prone and not actually very popular with the keyboard layout creator).

    I’d gladly give up my right winkey to have it act as a true compose key. It’d be nice also if my alt-gr were consistently completely different from ctrl-alt, but alas it’s not.

    ======================

    Chorded shortcuts are much better than massively multi-finger shortcuts. Ignore the whiners; they can always switch back to 2k3/6/5/whatever mode if they want to.

  45. Duncan says:

    "and non-English layouts are almost universally poor at handling those characters."

    So are UK / US keyboards. Anyone else get so teribly sick of having to use shift just to get the { character?

  46. Resharper has some kind of filtering .You can find it here http://www.jetbrains.com/resharper/

  47. XECODE.COM says:

    http://msdn.microsoft.com/vstudio/productinfo/roadmap.aspx — vb ִ vb ɵ ߰ϴ± :)&nbsp;vc++ .net 2003 ̹ ǥؿ ϴ ؼ ׷, managed c++ ɸ ܶ ߰ ̰, stl Ѵٴ ܿ…&nbsp;sql server 2000 2005 ׷̵?&nbsp;orcas longhorn ߸ ÿ̶…