Click here to Skip to main content
Click here to Skip to main content

Using the Google Desktop and ReSharper APIs

, 13 Sep 2006
Rate this:
Please Sign up or sign in to vote.
This article describes coding against the Google Desktop API to create a plug-in for ReSharper.

Sample Image

Introduction

The less I have to navigate a directory tree, the happier I become. The arrival of Google Desktop hails the "flattening" of the file structure, as finally there is something that can just find my file for me, right when I want it. I have been a little slow to adopt the Google Desktop Search, because it still wants to open a file in the default way. If I tell it to open a web.config file, a new instance of TextPad will open (fine). I start getting annoyed when I go to open a C# source file, and suddenly I'm waiting for a new copy of VS.NET to open. That's bad.

So I have begun the task of integrating Google Desktop into text editors, with this ReSharper plug-in.

With this plug-in, I hit Ctrl-Alt-Z, type in a file name, and two seconds later, I'm editing it. Yah!

If you use Google Desktop and ReSharper, you might be interested in this plug-in. If you haven't gone to ReSharper yet, maybe you'll be interested in turning this into a VS.NET plug-in?

Background

I chose to use ReSharper because it comes with some fancy PopupList user interface stuff. The next iteration will probably be more like the Common File dialog, and if possible, I will simply integrate with the Windows Common File dialog. Anyone knows how to do this?

I fooled around with the Google Desktop Native API for a long time before deciding that C# isn't the right language for doing that. Eventually, I found this .NET wrapper for the web interface to Google Desktop Search, which I included in the project.

Using the code

First, register the Action, with this bit from AssemblyInfo.cs:

[assembly : PluginTitle("OpenByGoogleDesktopSearch")]
[assembly : PluginVendor("Tyler Gannon")]
[assembly : PluginDescription("Find a file using 
            Google Desktop search and open it.")]
[assembly : ActionsXml("Resharper.GoogleSearchPlugin.Actions.xml")]
//  Don't forget to open Actions.xml and have a look in there.

Then you need a bit in Actions.xml:

The GDS.SearchFiles method returns a sorted array of SearchResult objects, filtered to only include results that correspond to files on the local file system.

Getting the search results looks like this:

IGoogleSearch search = GoogleSearchFactory.CreateGoogleDesktopSearch();
search.ResultsPerPage = 20;
search.ResultType = ResultTypes.DataSet;
IGoogleSearchResult searchResult = search.Search(query);
DataSet currentResult;

Now, iterate through them, and get rid of any junk.

foreach (DataRow row in table.Rows)
{
    if ("file".CompareTo((string) row["category"]) == 0)
    {
        object title = row["title"];
        object url = row["url"];
        if (DBNull.Value.Equals(title) || DBNull.Value.Equals(url))
            continue;

        object snippet = title;
        try
        {
            snippet = row["snippet"];
            if (DBNull.Value.Equals(snippet))
                snippet = title;
        }
        catch (Exception)
        {
            continue;
        }

        string urlString = (string) url;
        if (urlString.StartsWith("archive://"))
        //  I think that means the file is gone.
            continue;

        SearchResult result = new SearchResult((string) title, 
                                  urlString, (string) snippet);
        resultsToReturn.Add(result);
        currentResultCount++;
    }
    if (currentResultCount >= maxResults)
    {
        break;
    }
}

Now, make it so that file names most similar to the actual search query will show up first.

Array.Sort(resultsArray, new SearchResultComparer(query));

Making use of the ReSharper popup requires implementing a few interfaces:

  • IPositionProvider, which tells the system where it can present the popup.
  • IPopupListItemDescriptor, a list of which are given to the PopupList by the PopupListProvider. In this project, SearchResult implements that interface.
  • IPopupListProvider, which is the liaison between the GDS search and the PopUpList.
  • IPopupWindowContext, which provides general functionality around PopupWindows. I inherited my PopupWindowContext from PopupWindowContextBase, and then I only had to implement CreateDefaultPositionProvider(), which is defined as abstract on the base class.

The SearchPopup form code ties it all together:

public SearchPopup()
{
    InitializeComponent();
    textBox1.Enter += new EventHandler(TextBox1_OnEnter);
}

internal void UpdateList()
{
    if (textBox1.Text.Trim().Equals(string.Empty))
    {
        TrimWindowSize();
        return;
    }
    
    list = new EscapingPopupList(new SearchResultListProvider(
           GDS.SearchFiles(textBox1.Text, MAX_RECORDS_TO_SHOW), this));
    list.Escape += new PopupListEscapeEvent(TrimWindowSize);
    list.Show(positionProvider);
}

private void TrimWindowSize()
{
    this.ResizeRedraw = true;
    this.Size = textBox1.Size;
}

protected void TextBox1_OnEnter(Object Sender, EventArgs e)
{
    if (popupWindowContext==null)
        popupWindowContext = new PopupWindowContext(this);
    
    if (positionProvider==null)
        positionProvider = 
          popupWindowContext.CreateDefaultPositionProvider();
    base.OnEnter(e);
}

protected override bool ProcessDialogKey(Keys keyData)
{
    if (keyData == (Keys.Control| Keys.W) || keyData==(Keys.Escape))
        Close();
    
    if (keyData == Keys.Tab || keyData == Keys.Enter)
        UpdateList();
    return base.ProcessDialogKey (keyData);
}

Installation

Once it's built and ready, you need to register the plug-in with ReSharper, and finally you must set up a Command Key. Copy the DLL into its own subdirectory of the PlugIns directory underneath where ReSharper is installed. The directory should be named the same as the plug-in. In this case, the assembly is named Resharper.GoogleSearchPlugin, so that's what I named the directory. Then, start VS.NET, and do the following settings in the ReSharper Plug-Ins dialog, followed by the Keyboard tab on the VS.NET general options:

And you're ready to go! Have fun.

History

  • 0.1 - Initial release.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

gone_cat

United States United States
No Biography provided

Comments and Discussions

 
GeneralResharper 2.5 Pinmembermmwlada21-Jan-07 9:49 
QuestionResharper API documentation Pinmemberd_menta13-Nov-06 5:18 
GeneralErrors :( PinmemberStevenMcD26-Oct-06 20:14 
'>' is an unexpected token. The expected token is '"' or '''. Line 1, position 62.
 
Thats the error i get when deploying my app to our devServer. working locally it works fine though. anyway ideas?

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 13 Sep 2006
Article Copyright 2006 by gone_cat
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid