I <3 Steve McConnell*
Coding Horror
programming and human factors
by Jeff Atwood

October 26, 2005

Google search VS.NET macro

Here's a handy little Visual Studio .NET macro which searches for the currently highlighted term in Google. The search is launched as a new tab within the IDE when you press

Alt+F1

I know what you're thinking: you've seen this macro before. Yeah, but this one goes to eleven. It actually works with any highlighted text in the IDE -- including highlighted text from the Output window:

google_search_macro_screenshot.png

Here's the macro code (updated 11/26/2007*):

Public Sub SearchGoogleForSelectedText()
    Dim s As String = ActiveWindowSelection().Trim()
    If s.Length > 0 Then
        DTE.ItemOperations.Navigate("http://www.google.com/search?q=" & _
            Web.HttpUtility.UrlEncode(s))
    End If
End Sub

Private Function ActiveWindowSelection() As String
  If DTE.ActiveWindow.ObjectKind = EnvDTE.Constants.vsWindowKindOutput Then
    Return OutputWindowSelection()
  End If
  If DTE.ActiveWindow.ObjectKind = "{57312C73-6202-49E9-B1E1-40EA1A6DC1F6}" Then
    Return HTMLEditorSelection()
  End If
  Return SelectionText(DTE.ActiveWindow.Selection)
End Function

Private Function HTMLEditorSelection() As String
  Dim hw As HTMLWindow = ActiveDocument.ActiveWindow.Object
  Dim tw As TextWindow = hw.CurrentTabObject
  Return SelectionText(tw.Selection)
End Function

Private Function OutputWindowSelection() As String
    Dim w As Window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
    Dim ow As OutputWindow = w.Object
    Dim owp As OutputWindowPane = ow.OutputWindowPanes.Item(ow.ActivePane.Name)
    Return SelectionText(owp.TextDocument.Selection)
End Function

Private Function SelectionText(ByVal sel As EnvDTE.TextSelection) As String
    If sel Is Nothing Then
        Return ""
    End If
    If sel.Text.Length = 0 Then
        SelectWord(sel)
    End If
    If sel.Text.Length <= 2 Then
        Return ""
    End If
    Return sel.Text
End Function

Private Sub SelectWord(ByVal sel As EnvDTE.TextSelection)
    Dim leftPos As Integer
    Dim line As Integer
    Dim pt As EnvDTE.EditPoint = sel.ActivePoint.CreateEditPoint()

    sel.WordLeft(True, 1)
    line = sel.TextRanges.Item(1).StartPoint.Line
    leftPos = sel.TextRanges.Item(1).StartPoint.LineCharOffset
    pt.MoveToLineAndOffset(line, leftPos)
    sel.MoveToPoint(pt)
    sel.WordRight(True, 1)
End Sub

I tested the macro in VS.NET 2003 and VS.NET 2005 and it works great with no modifications in either environment. Here's how to install it:

  1. go to Tools - Macros - IDE
  2. create a new Module with a name of your choice under "MyMacros". Or use an existing module.
  3. paste the above code into the module
  4. add a reference to the System.Web namespace (for HttpUtility) to the module
  5. close the macro IDE window
  6. go to Tools - Options - Environment - Keyboard
  7. type "google" in the Show Commands Containing textbox. The SearchGoogleForSelectedText macro should show up
  8. click in the Press Shortcut Keys textbox, then press ALT+F1
  9. click the Assign button
  10. click OK

It's really quite handy; ALT+F1 is a totally natural chord and a logical superset of F1.

* Courtesy Bojan Bjelic, the macro now works in .aspx source (html) view.

Posted by Jeff Atwood    View blog reactions

 

« The Cognitive Style of Visual Studio Copying Visual Studio Code Snippets to the Clipboard as HTML »

 

Comments

Love it. It's the first macro that I can use on a regular basis so I'll remember the short cut. Have you tried it in the Html view of an aspx page?

Bob Mercier on October 26, 2005 09:02 AM

That is really nice. Thanks a lot I will be putting that to good use.

Matthew Hinton on October 26, 2005 10:25 AM

Neat. I'll probably tweak it so it launches an external IE window though.

Scott Williams on October 26, 2005 10:57 AM

Great stuff!

I changed the URL to hit MSDN. Here is the line of code with the URL:

DTE.ItemOperations.Navigate("http://search.microsoft.com/search/results.aspx?view=msdn&qu=" & HttpUtility.UrlEncode(s))

Brett Woodward on October 26, 2005 11:19 AM

There are very few macros that are actually usefull. This one is definitly tops!

If someone gets the tweak to open in a new browser, can you post the code?

John on October 26, 2005 12:17 PM

> If someone gets the tweak to open in a new browser, can you post the code?

If you want IE to open in a seperate window instead of an IDE tab, just change..

DTE.ItemOperations.Navigate

to..

Diagnostics.Process.Start

Jeff Atwood on October 26, 2005 12:32 PM

As it is, using the macro in VS.net 2003 gives me this error:
"Name 'HttpUtility' is not declared." I had to import the System.Web namespace too, since HttpUtility is unqualified:
Imports System.Web

So I fixed that error. Next problem is that it doesn't find any selected text.

In debugging, this is true:
DTE.ActiveWindow.Selection Is Nothing.
But this (change) is false:
DTE.ActiveDocument.Selection Is Nothing

So changing ActiveWindowSelection thus fixes it for me:
Return SelectionText(DTE.ActiveDOCUMENT.Selection)

BTW, I also modified it to use Google's Microsoft-targeted search URL:
http://www.google.com/microsoft?q=

I'd love a way for it to find the word the cursor is currently on, withOUT needing to select it. (That's how VS.net's integration with MSDN Library works.)

Rob on October 26, 2005 12:41 PM

> I'd love a way for it to find the word the cursor is currently on, withOUT needing to select it. (That's how VS.net's integration with MSDN Library works.)

I don't care for this behavior personally, but I guess it's better than doing nothing, which is what happens when you hit ALT+F1 with nothing selected. I added it to the code in the entry..

Jeff Atwood on October 26, 2005 01:32 PM

> Next problem is that it doesn't find any selected text

I can't duplicate this at all. The IDE always finds my selected text using DTE.ActiveWindow.Selection.

How are you doing this?

Jeff Atwood on October 26, 2005 01:46 PM

Awesome! I added a CTRL+G mapped macro that did the same stuff but used http://www.google.com/q=site:msdn.microsoft.com+ as the query URL so that you can search MSDN through Google's interface.

Bill Brown on October 26, 2005 06:42 PM

Here's how to open the P/Invoke website for native win32 commands:

DTE.ItemOperations.Navigate("http://www.pinvoke.net/search.aspx?search=" & HttpUtility.UrlEncode(s) & "&namespace=[All]")

Jan Stavngaard on October 27, 2005 07:19 AM

if you change the -

DTE.ItemOperations.Navigate("http://www.google.com/search?q=" & HttpUtility.UrlEncode(s))

to

DTE.ItemOperations.Navigate("http://www.google.com/search?q=.net " & HttpUtility.UrlEncode(s))

then you get searches based on .net only

k on October 27, 2005 11:13 AM

For this sort of behavior elsewhere than MSVC.net I'd like to recommend ClipX (a tiny clipboard history manager) at http://bluemars.org/clipx/ which has the nifty feature of opening a browser with a Google search for the current clipboard contents with Control + Shift + G (or any other key you wish to configure for it.) Not quite as streamlined in that you have to first copy the text you wish to search but still quite useful.

Brennan on October 27, 2005 01:42 PM

Does the change to Diagnostics.Process.Start work for anyone? For me it causes this error: "The requested lookup key was not found in any active activation context."

Alek Davis on October 27, 2005 07:41 PM

Ever useful insight as always Jeff;) This one rocks!

Scott Schecter on October 28, 2005 11:32 AM

Great.

For shared macros, I prefer just fully qualifying the calls rather than requiring an import - more portable:

System.Web.HttpUtility.UrlEncode(s))
vs.
HttpUtility.UrlEncode(s))

Jon Galloway on October 28, 2005 12:35 PM

Jon -- regardless of the way the call is qualified, you'll still have to manually add a reference (via the right click Add Reference menu) to the IDE module.

If that wasn't required, I'd totally agree with you.

And I also agree that simply "HttpUtility" alone is no good because it gives the developer no hint as to what reference is required. But I think "Web.HttpUtility" should be enough to figure it out. I mean, c'mon. ;)

Jeff Atwood on October 28, 2005 01:08 PM

I posted a article that explaind how to use googled search in Visual Studio 2003 about 2 years ago, and, of course, your version is better than mine. :-)

http://www.codeproject.com/macro/googlemacro.asp

WooSeok Seo on October 29, 2005 12:21 AM

How can you get green text on a black background in your output window..? Great macro, cheers!

Jase on November 29, 2005 12:42 PM

> How can you get green text on a black background in your output window..?

It's only possible in Visual Studio 2005, via Tools, Options, Environment, Fonts and Colors, [All Text Tool Windows]

Jeff Atwood on November 29, 2005 01:13 PM

Strange: When I try to "Add Reference" in the macro IDE, its disabled.
?

LJ on December 13, 2005 03:20 PM

Great MACRO..... Just love it...

Bikash on December 15, 2005 12:02 AM

Got past my "Add Reference" problem as if by magic....
Anyway, I added one more public method to my code, because I love to use Google to search a specific site, especially MSDN:

Public Sub SearchMSDNViaGoogleForSelectedText()
Dim s As String = ActiveWindowSelection().Trim()
If s.Length > 0 Then
DTE.ItemOperations.Navigate("http://www.google.com/search?hl=en&q=site%3Amsdn.microsoft.com+" & _
System.Web.HttpUtility.UrlEncode(s))
End If
End Sub

LJ on December 15, 2005 04:09 PM

To start in new browser window, I found this works:

Diagnostics.Process.Start("iexplore.exe", "http://www.google.com/search?q=" & System.Web.HttpUtility.UrlEncode(s))

Cool macro :)

Richard McCormack on December 15, 2005 05:29 PM

My main motivation for using this macro was that the VS built-in F1 help is so painfully slow. However, after switching to the macro I discovered the msdn2 site is also terribly slow. It seem to take a lot of time filling up its tree view on the left side.
Anyway, I'll certainly keep a copy of this macro in case Microsoft ever speeds up the msdn2 site...

catweazle on April 26, 2006 08:36 AM

I found this workaround for the Process.Start error "The requested lookup key was not found in any active activation context.":

Process process = new Process();
process.StartInfo.FileName = "rundll32.exe";
process.StartInfo.Arguments = "url.dll,FileProtocolHandler \"" + url + "\"";
process.StartInfo.UseShellExecute = true;
process.Start();

It works the same as Richard's solution, only it will use the default browser, nicer for the Firefox fanboys ;).

Berend on September 5, 2006 11:21 PM

Nice! When I switched to Visual Studio 2005 I quickly gave up on the built in help.

I could never quite figure it out, it never seems to do what I expect it to and searching online is much easier and faster.

Microsoft seems to be bent on making every Visual Studio version's help system worse than the one before it and VS2005 has sunk to new levels of sheer badness and overengineering.

It should be the single most easiest part of the program to use, I can't fathom what they were thinking.

Thanks!

John on September 22, 2006 08:19 AM

Excellent macro - thanks very much for this. I'm now opening into a new tab in firefox when Alt-F1'ing!

Warren Legg on October 3, 2007 09:01 AM

The macro is not working for text selected in the Source view of an ASPX page. It works on all other views and panes. (VS 2005).

ajmastrean on November 26, 2007 05:42 AM

It works in VS2008 as well.

zaander on January 31, 2008 11:53 PM

Great stuff! I was just thinking of writing such a macro when I found yours! Thank you.

Wole on March 21, 2008 02:11 AM

Great stuff! I was just thinking of writing such a macro when I found yours! Thank you.

Wole on March 21, 2008 02:12 AM

Thanks! Here is another simple search macro that works everywere on Windows, not only on Visual Studio.
/Mark

Mark on March 28, 2008 07:51 AM

Sory!! here is the link: http://www.winutilis.net/html/misc/vbs/clpbs.asp

Mark on March 28, 2008 07:53 AM

A nice idea. I just wish I could get it to work.

Al on May 1, 2008 02:09 AM







(hear it spoken)


(no HTML)




Content (c) 2008 Jeff Atwood. Logo image used with permission of the author. (c) 1993 Steven C. McConnell. All Rights Reserved.