Writing approachable code: Introducing the hyperaddin for Visual Studio!

A few years ago now, several of us on the .NET Runtime team where lamenting how unapproachable the code base was for new developers to the team.    We agreed that more commenting would certainly help the situation, but that alone was not enough, because you also need to FIND the comments WHEN they are relevent for the comments to actually be useful.   Typically the most useful comments are not about a particular line of code, but information about the purpose of a whole method, class, or subsystem, and what the global invarients are.   Finding these very useful comments is often not a trivial exercise. 

It occured to us at the time that this problem is not so different from finding relevent data on internet, and that having hyperlinks would help alot to ‘channel’ people to important relevant comments.  This was the genesis of the HyperAddin.   The idea is that Visual Studio already supported having hyperlinks in comments (any strings starting with http:// becomes a link that you can Ctrl-left click on).    The idea is to add a new string called code:identifier  which turns into a hyperlink that looks up the definition to identifier.  Now it is possible for one part of the code base to refer to another by symbolic name.   

Taking our cue from HTML, we added the capability of sub-file anchors.  Any comment of the form

  • // #SomeIdentifier

Defines an anchor in that file called SomeIdentifier.  You can then refer to it by the hyperlink code:identifier#tag.  Like HTML, this is a hyperlink to code:identifier (which gets you to the correct file) followed by a search on that ‘page’ (file) for ‘tag’.  The result is that it is now trivial for one comment to refer to another.  

With this simple change, it is now possible to write a very nice overview comment and refer to it in dozens of places.  Having used it for several months now, I find it very constraining on those occasions that I am not writing code in visual studio, and thus do not have my code hyperlinks.    In retrospect I am amazed that someone did not think of this earlier (which is a hallmark of a good idea).

There is more to say about what the hyperaddin can do for you (stay tuned), but this blog entry is mostly about getting you to try it.   Just today I published the addin on codePlex as HyperAddin.  Please click on the link and follow the installation instructions (it is an XCOPY deployment).    If you use Visual Studio, give it a try right now.

If you like the capabilities of HyperAddin and wish that Visual Studio had this feature, you can vote on this here.  To vote, click on the ‘Sign in to Rate’ (and register if necessary), and then click on the number of stars in the rating box that corresponds to the value of this feature.   The more people who vote, the more likely this feature is to get into Visual Studio.

Comments (15)

  1. Peter Ritchie says:

    That sounds very useful.  More useful still would be to automatically make hyperlinks of words (either within a fully-qualified name or without a namespace) in comments that match types in the current project.

  2. Very nice. Any plans on getting this integrated with csc /doc and SandCastle?

  3. Making hyperlinks automatically is an interesting addition, but I am skeptical of it without some sort of marker that indicates the intent that it is a hyperlink.  Part of what make hyperlinks useful is the knowledge that someone thought it was useful to create the link.   When you add them automatically you loose this.    I think a good compromise is a one character marker (eg #), that indicates intent, but is trivial to type.    We stuck with code: because we could hook into existing infrastructure more easily, and was less ‘magical’ (you could guess at what it means even if you did not have the hyperlink software.

    I have not thought alot about integration with SandCastle.  

  4. Peter Ritchie says:

    With just the code: prefix you loose the ability to add hyperlinks to XML comments.  propgating "code:" into your code documentation would be a big no no.

    The drawback of code: is they are aren’t validated.  If you add "code:gibberish", it will display as a hyperlink but when you ctrl-click it it simply gives you a warning "could not find symbol…" way down in the status bar.  Where as if "gibberish" were a type it would display as a hyperlink, otherwise it would simply be another word–I’d never have broken links…

    At the very least, supporting <see cref="Namespace.TypeName"> would be useful.

  5. The code: hyperlink is not intended for external documentation.  After all the code does not ship with the documentation and thus linking to it would be inappropriate.   If on the other hand, it is just an application without a formal API surface, or you ship the source with your API surface, then it can make sense.  It depends on your needs.  

    It is also true that there is no validation of the hyperlinks.  That is on the TODO list.   It would also be nice if you had completion (intellisense), but that requires deaper integration with VS.   The idea of supporting hyperlinks for cref XML tags is also an idea that has come up before, but also requires deeper integration with VS to do (I don’t create the hyperlinks, I just register that code: is a tag that can be a URL and VS turns it into one).

    Ideally, this is something that would be provided by VS, however VS gets alot of feature requests that lower the probability that this one will get funded.  The way to get this one actually approved is for enough people to send feedback (eg on http://connect.microsoft.com/feedback/default.aspx?SiteID=210) asking for it.  However no one will do that unless they can actually try it out and discover its usefulness   A chicken or egg problem.  We break this cycle by providing something (eg HyperAddin), that allows people to try out the feature.  If it becomes popular, it is relatively easy to get Visual Studio to add it (and fix the issues you describe).

    That’s the plan…

  6. I have updated the body of the blog to include a hyperlink to a sugestion to add this capability to Visual Studio directly.  If anyone is interested, please take a moment to vote on this suggeestion.

  7. dalevine@ra.rockwell.com says:

    I just tried it out and I like it. Here’s some quick feedback after 10 minutes of playing with it.

    1. Intellisense. When I type in "code:" I really want to see a list of what has been defined. In a large system with lots of anchors this will be a problem.

    2. Word wrapping in comments –> GREAT! I’ve been wanting this for a long time and even if I don’t use the hyper links I will benefit from the word wrap and continuation of comments.

    3. When "Enter" is pressed after a commented line a new comment line is always created. I’d prefer it to stop adding new comment lines if the previous comment line is empty and just go to a blank line.

    4: GoOut. Cool feature. How about a Go Out for #regions (takes me to the beginning of a region), and a GoOut for code in try-catch-finally, go to the beginning of the block, or to the previous block if at the beginning of a block. e.g. if in the finally section, take it to the beginning of the finally, and from there to the catch block, and from there to the beginning of the try block.

    5. Formatting. When I reformatted a commented block that I later edited it moved the starting column to the right. It should maintain the same starting column.

    When reformatting a selection of text it moved the starting column of lines 2,3,4 to the right but left the starting column of line 1 as-is, resulting in a jagged display of text.

    On the whole, very nice. Thanks

  8. Great feedback.  Certainly the intellisense feature is needed, but is also hard to do without deeper integration into VS (which I am not ready to attack).  

    The issue of whether comments should be continued or not is problematic, as there are times when you want the comments to continue and times you don’t and it is hard to infer from context.    I the idea of using a blank line as a hint is interesting (although I think I would want it to be two blank lines.  

    The current solution to this problem is that Ctrl-Z will undo the comment insertion, so if you wanted to type code, and it make a comment, you are one character away from fixing it.  

    The idea of leaveraging regions or code blocks (as both hyperlink anchors, and for Go Out), is interesting.  

    I have to investigate the formatting issue you describe (I am not certain I can repro it given your description).  

  9. For those interested.  I have posted the source code for HyperAddin (see http://www.codeplex.com/hyperAddin/SourceControl/ListDownloadableCommits.aspx).  Hopefully you will find the code very approachable (I did go to some effort to make it readable), so people can tinker with it.  

  10. I follow Brad Abrams blog and saw that he posted on a very nicely implemented Visual Studio add-in component…

  11. dalevine@ra.rockwell.com says:

    Thanks for making the source code available.

    I ran into a problem with the add-in, and I think I fixed it (or worked around it) based on the source code you posted.

    The problem was that if you were in a xml comment area (e.g. the header for methods) it would treat that as if it were in a regular comment area. This was ok for word wrapping (I kind of liked that) but it caused problems with the XML intellisense.

    Normal behavior is that when you are in the xml comment area and enter "<" it brings up a list of available entries, such as "== param name="Arg1".  If you then press the Enter key it copies that text down into the xml comment so that you can add your comment into the xml field.

    However, the add-in swallowed the enter key and the text was never copied down. I found this annoying so I modified the source code as follows:

    In source file HyperAddin.cs, in method BeforeKeyPress(…) I added two lines of code.


                       // Are we in a comment???

    string xmlStart = "///"; // Must also check to see if we are in xml comment area

    if ( ( String.Compare( lineText, commentCharsIdx, commentStart, 0, commentStart.Length ) == 0 )

    && !( String.Compare( lineText, commentCharsIdx, xmlStart, 0, xmlStart.Length ) == 0 ) )


    <more code>

    Basically, this checks if we are editing in the xml area, and if so, it ignores all entries. I added the xmlStart string and the string.Compare

    I’d prefer it to be smarter so that word wrap still functions within the xml comment area, but which ignores user input when selecting an item from Intellisense, but I do not know enough about the VS addin model to be able to figure out how to do this.

    There may be other areas that need to check for this, but this solved the problem I was having and I did not look any further.

    Thanks again for the source code, I’m sure I’ll refer to it when I write my own addins.

  12. Thanks for the feedback.  I actually did not know that intellesence also used the return key as a competion character (I have always used tab).   There is actually logic in HyperAddin so that XML intellisense works for tab.  It can certainly be fixed to to both tab and return.   I will do this at some point.


  13. Mladen Mihajlovic says:

    How about updating this addin to work for Vs2010 and Vs2012? It's amazingly useful!

  14. Yes, I have wanted to do this literally for years.    

    Some progress has been made, and it mostly is about getting the time to do it, as it is frankly much easier to do it in VS2010/2012 than for VS2008 (there is a sample for making hyperlinks in the editor that is available already)   No promises however.  

  15. Damyan says:

    I was using this amazing addin with VS2008 as key component as I need FAST navigation in code in that style. And it is a bad surprise that it not work on VS2012 I'm force to go as I need to use NET.4 0.

    Who is actually the author of this great addins? Could you connect me to him, my email is: msoftbg@dir.bg