Why Not Just Paste a URL?

Of course, you could paste the URL as well, but Linkify has some advantages:

The source remains more readable.

Linkify allows everything that a creative ShellExecute call can do: open URLs, open documents, run programs.

If your bug tracker moves to a new URL, just reconfigure the Linkify protocol and you are done for all links.

Installing

The article now contains an installer that puts it in one of the five folders that Visual Studio 2005 and 2008 searches for add-ins in by default. However, if you have changed your add-in search folders or you run into other funny problems, here is how to install manually:

To install manually for Visual Studio 2005, unzip the two files from LinkifyAddin.zip to your Visual Studio Addins folder, e.g. \Documents and Settings\<user>\My Documents\Visual Studio 2005\Addins where <user> is either your user name or "All Users". When you start Visual Studio again, Linkify appears in the Tools menu. From there you can also put it on a toolbar button and/or assign a hotkey to it.

Visual Studio 2008 Notes

Installation is similar for Visual Studio 2008. The addin binary is the same for both versions of Visuaol Studio, and two .AddIn files are included - one for each Visual Studio version. I haven't seen bad side effects when placing both addin files in the search path for one Studio instance (Except that my AddIn manager recognizes it twice).

I haven't been able to test the installation and the latest binaries on VS2008 yet, please report any errors you find.

How to Configure

Holding down Shift while clicking Linkify or starting it while on unrecognized text opens the configuration dialog. There you can manage the list of recognized protocols and associate them with URLs and other commands.

Example

Prefix=bugz:

EXE/URL=http://companyserver/bugtracker/showbug.asp?id=*

Clicking Linkify while the cursor is on bugz:666 opens http://companyserver/bugtracker/showbug.asp?id=666

The asterisk (*) is replaced by the link text from the source code.

Configuration

Prefix:

The protocol prefix. You can use any character sequence here, but it is recommended to trail it with a colon.

End of Link:

Configures how the end of the link is detected after the protocol was recognized:

Space scans until a space is encountered

Default uses some heuristically selected characters and should be (mostly) equivalent to the algorithm used in previous versions

Remainder of Line uses everything that follows on the line, no questions asked

Regular Expression allows to specify a regular expression that selects the link form the remainder of the line

Note that your link text may use single or double quotes directly after the protocol prefix to override Space or Default.

Regular Expression:

(only available if End of Link is set to Regular Expression)A regular expression to extract the link from the remainder of the line.

Description

Just so you recognize what this was supposed to do.

URL Escape:

Escapes the link text according to URL rules, which is usually necessary when your target is a URL.

Confirm Execution:

Shows a confirmation box before running the command. Recommended if you are doing something irreversible or dangerous, or prefer being asked.

Expand Environment Strings:

if checked, environment strings in the URL/exe parameter are expanded before calling ShellExecute. This allows generic references such as %PROGRAMFILES%\SomeTool\SomeTool.exe, and other trickery.

URL/EXE:Arguments:

filename and arguments parameters for ShellExecute / ProcessStartInfo. The first takes an executable and URL or a document path. If you specify an executable, you may also want to specify the command line arguments for it.

Utility URL:

A link to more information / installation instructions for the prefix. The link is displayed when an error occurs or you enable Test Mode.

If the prefix calls a custom tool, you could link to installaiton instructions here. Also, you could provide a page with additional details here.

More/Export...

Exports your settings to a file so you can move it to another PC.

More/Import...

Imports settings from a file. You can replace all existing protocols, add or merge them.

More/Add Defaults...

Adds the default (sample) protocols to the list, in case you deleted them but want them back.

More/Shift forces Config...

Enables / Disables going directly to the configuration dialog when Shift is pressed while clicking on Linkify. (on by default)

More/Test Mode...

Enables / Disables and extended confirmation dialog for all protocols (overrides the Confirm Execution option). This dialog contains additional information on what was recognized on the line and is intended for testing.

More/About...

Puts Linkify in power save mode to prevent global warming. (to be implemented)

How Link Text is Recognized

The link text parser is all-ugly manual scanning for specific characters. I'm quite happy with the results, but YMMV.

To find the prefix, Linkify scans from the caret poistion to the left until it finds a whitespace or the beginning of the line.

At this position check if the text matches a known protocol prefix. Comparison is case sensitive. I end my prefixes with a colon, but you don't have to.

If it doesn't, but the first character following is an opening parenthesis, skip this and check again. (hack)

The End of Link setting now determines how the link is recognized.

Remainder of Line uses the rest of the line.

Regular Expression uses the Regex specified in the settings. If the regular expression contains a named group "link", it uses this value. Otherwise, if it contains any group, it uses the first one encountered. Otherwise, it uses the entire match.If this is all gibberish to you, try Jim Hollenhorst's 30 Minute Regex Tutorial and his Expresso.

Space scans to the next whitespace (or end of line).

Default scans to the next terminating character: ). or ;

The settings Space and Default allow single or double quotes to enclose an expresison that does contain terminating characters:

The Source Code

Source code is included with this add-in, although it isn't recommended reading (FxCop would probably handcuff me). It was a bit tricky to extract the text under the cursor using a sequence of manipulations to the current selection. I've changed that now to extracting the entire line and selection positions and working my way from there.

Visual Studio allows add-ins to save settings in a Globals object, but I found that this works only for strings. Since the settings class is serializable, I serialize to a memory stream and then convert the contents to a base-64 string. It's weird, I know, but I wanted to avoid any Unicode troubles. The settings can be imported from and exported to a file through the configuration dialog. The remaining code (configuration form, etc.) is pretty much straightforward. Most of the initialization is code created by the add-in wizard. If you are curious, you can diff my code against a default add-in wizard-generated project.

Example: Linkifying CodeProject

To search articles on The Code Project, you can add the following settings:

Articles by keyword search

Prefix: cp:

URL: http://www.codeproject.com/info/search.aspx?artkw=*&sbo=kw

Articles by author search (currently isn't available)

Prefix: cpian:

URL: http://www.codeproject.com/info/search.aspx?st=au&target=*

cp:Linkify will search for articles containing Linkify

cpian:shog9 will search for articles by shog9

It doesn't make much sense; it's just a little tribute...

License

The add-in in binary form is free for any use (including development of a commercial application) and may be redistributed without charge, as long as it remains unmodified and the copyright notice stays intact. Source code of the add-in itself is free for non-commercial use. Please share bug fixes and improvements here. Inclusion in commercial add-ins on request.

Enjoy!

History

Aug 15, 2006: Initial release

Aug 20, 2006

Fixes:

No more error message at first start after installing (duh!)

Few improvements to file import/export

Linking to CP added to defaults

Aug 27, 2006 (Version 1.1)

Fixes:

Error message(s) at first start (sorry folks... it should be really gone)

* Note: if I accidentally broke your existing links, first see if changing the configuration for that protocol helps. If not, please leave a message with the protocol prefix and the comment line in question.

License

Share

About the Author

Peter is tired of being called "Mr. Chen", even so certain individuals insist on it. No, he's not chinese.

Peter has seen lots of boxes you youngsters wouldn't even accept as calculators. He is proud of having visited the insides of a 16 Bit Machine.

In his spare time he ponders new ways of turning groceries into biohazards, or tries to coax South American officials to add some stamps to his passport.

Beyond these trivialities Peter works for Klippel[^], a small german company that wants to make mankind happier by selling them novel loudspeaker measurement equipment.

Where are you from?[^]Please, if you are using one of my articles for anything, just leave me a comment. Seeing that this stuff is actually useful to someone is what keeps me posting and updating them.Should you happen to not like it, tell me, too

Hello,
A big big thank for your addin - really so useful! Really wondering why MS didn't include it natively into VS. You should propose it to them (no kidding).

I may just have one issue with it: when using a link of the form
// wiki:"my key in many words"
I systematically loose the last character (the 's' of 'words' here) in the link that linkify generates. I precise I'm using the default 'end of link' and that I checked the "URL -escape parameter".

And to finish, one strong whish about linkify: that it support "mouse hovering", ie links being detected when the mouse is over them, as VS currently does for regular hyperlinks...

Glad to see that you're both maintaining the addin and that you quickly solved the issue! I really can't live without it: all our web tools (wiki, bug tracker...) were already linked together, but we missed the link with VS.NET and now we have it.

If you have some tip about where/what to look for for mouse integration, I'd glad to know as I've already spent some time on it but without any luck. In the meantime, we've assigned a key shortcut to the Linkify menu item and that's pretty efficient.

May I bring another suggestion which could be very useful (at least for me)? My idea would be to be able to define a prefix which would be separated from the keyword by a blank space... That could look trivial but that indeed would have a huge consequence: the ability to automatically 'jump' from a class name to some external tool (a documentation wiki in our case). To be more clear, when I have in my code:

publicclass XXX
{
...
}

my whish would be that Linkify would recognize the prefix 'class' and isolate XXX as the keyword. That way, I would automatically jump to my wiki portal on the page dedicated to that class...

--> update I did it actually, but my hack is hardcoded. I simply ignore the first empty spaces between the prefix and the link itself. Here's my Connect.cs in MatchProtocol (line 277):

Thank you very much for the kind words - as I've said before, what drives me is to see that these things are actually useful to someone.

The update I'm preparing allows a regular expression for matching the parameter, it is still experimental and I still have to verify that it actually works as intended. It should do what you need, though I agree adding an "ignore lead spaces" option is bit simpler to use

Maybe lead spaces can be ignored generally - I believe avoiding options is good - let me consider that.

I'm Chris wrote:

PS: suggestion number 2: why wouldn't you move the Linkify addin to sourceforge or codeplex so that others (me...) could contribute to it?

Tough question. I don't trust Open Source to be a good thing by default, my own experiences are minimal but tend towards the negative. for the time being, I'd like to maintain it here -including contributions etc.

We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CPblog: TDD - the Aha! | Linkify!| FoldWithUs! | sighist

Thanks very much for the update.
I've just upgraded, and all the 'rules' we defined still works fine.

Furthermore, we added (but maybe I already told you) a little enhancement which is to launch a web page into VS.NET's internal browser rather than into an external one. This was a requirement from our dev team, and I must say it's nice not to have to jump between application but to stay in a single "window".

As there is a couple of classes impacted (but in a light way), I'm not going to post the changes here. Simply tell me if you want me to email them to you.

Hello peterchen, I have converted the addin to VS 2008 and uploaded the source at http://www.mediafire.com/download.php?8mhgnyfnnzz[^]. The setup project was not successfully converted there was a dependency on a custom build rule, details are in the UpgradeLog folder. I have tested and it works well on my machine but if there are problems let me know I will try to fix them.

As far as I know, VS2008 has full binary compatibility with VS2005 plugins. All you need to (apparantly) do is duplicate registry entries. Where you had hklm/Software/Microsoft/Visual Studio 8/... you use hklm/Microsoft/Visual Studio 9.0/... (note the .0).

I'm interested in hearing about what wiki you use for your development wiki. This is something I (and some other co-workers) have been interested in implementing recently, but we're not sure which platform to start with. Thanks in advance.

The main reasons I chose it are:
- Doesn't require a DBMS (although this makes it flexible, it is not always a good thing due to performance).
- Elegant
- PHP Based
- Simple to setup and use.
- Supports plug-ins

If you want to compare most (if not all) of the available wiki engines, you can visit the following site:http://www.wikimatrix.org[^]