Using Keyconfig

If you use many web applications like GMail and Remember the Milk, you may want to get access to them using a single key binding. In Firefox you can use the following snippet together with the Keyconfig extension to

  • cycle between all tabs matching the regular expression re
  • if no tab matches, open a new tab showing url
function openOrCycle(url, re) {
    var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
        .getService(Components.interfaces.nsIWindowMediator);
    var browserEnumerator = wm.getEnumerator("navigator:browser");

    // Check each browser instance for our URL
    var found = false;
    while (!found && browserEnumerator.hasMoreElements()) {
        var browserWin = browserEnumerator.getNext();
        var tabbrowser = browserWin.gBrowser;

        // Check each tab of this browser instance
        var numTabs = tabbrowser.browsers.length;
        var currentIndex = tabbrowser.tabContainer.selectedIndex;
        var nextIndex = (currentIndex + 1) % numTabs;
        for (var index = nextIndex;
             index != currentIndex;
             index = (index + 1) % numTabs) {
            var currentBrowser = tabbrowser.getBrowserAtIndex(index);
            if (re.test(currentBrowser.currentURI.spec)) {

                // The URL is already opened. Select this tab.
                tabbrowser.selectedTab = tabbrowser
                    .tabContainer
                    .childNodes[index];

                // Focus *this* browser-window
                browserWin.focus();

                found = true;
                break;
            }
        }
    }

    if (!found &&
        re.test(tabbrowser
            .getBrowserAtIndex(currentIndex)
            .currentURI.spec)) {

        // The URL is already opened. Select this tab.
        tabbrowser.selectedTab = tabbrowser
            .tabContainer
            .childNodes[currentIndex];

        // Focus *this* browser-window
        browserWin.focus();
        found = true;
    }

    // Our URL isn't open. Open it now.
    if (!found) {
        var recentWindow = wm.getMostRecentWindow("navigator:browser");
        if (recentWindow) {
            // Use an existing browser window
            if (window._content.document.location.href == "about:blank") {
                window._content.document.location.href = url;
                window._content.focus();
            } else {
                recentWindow.delayedOpenTab(url, null, null, null, null);
            }
        }
        else {
            // No browser windows are open, so open a new one.
            window.open(url);
        }
    }
}

openOrCycle("https://mail.google.com/mail/#inbox",
            /https?://mail.google.com/);

The snippet is based on examples from MDC.

Using Xmonad and Prism

If you use Xmonad and want very fast access to tasks like sending a mail, checking your calendar or marking a todo-item as completed, you may consider using Prism. You can assign a key binding in Xmonad to bring focus to a given Prism window – check out the WindowGo and NamedScratchpad modules.

Unfortunately the only thing distinguishing Prism windows  is the window title, so we need to force the title to stay fixed using a Greasemonkey script. You will need Teramako’s Greasemonkey build for Prism to do this, and something like the following:

// ==UserScript==
// @name           title-gmail
// @namespace      mntnoe.com
// @include        *
// ==/UserScript==

document.title="Gmail";

Note that some web applications will update the title dynamically, so you may need to adjust your predicate to account for that. For instance, GMail will update the title to “Gmail – Inbox (3) – foo@gmail.com”, so our predicate will read

className =? "Prism" <&&> fmap ("Gmail" `isPrefixOf`) title

It is a hack, but it works quite well 🙂

My complete solution is based on NamedScratchpad and makes sure that only one Prism window is shown at a time, enabling you to switch fast between web applications. I will post it together with my current Xmonad setup when I get time.

http://github.com/teramako/greasemonkey-for-prism