Firefox — How to open a link (to any text-based file) in Vim?

First of all, Firefox bases the settings in "Choose Helper Application" on system settings, so there's no simple way to configure that.

An even better solution, usability-wise, is to use the Firefox extension called "Open With" https://addons.mozilla.org/en-US/firefox/addon/open-with/

It says it's for web browsers, but it turns out it could be any program — it just calls he program with the URL as the first argument.

Next, I wrote a Python script:

import sys, os, re, tempfile, urllib, urlparse, time

handler, url = sys.argv[1:3]
match = re.match(r".*(\.[A-Za-z_]+)$", urlparse.urlparse(url).path)
tmpfile, tmpfile_path = tempfile.mkstemp(suffix=match.group(1) if match else '')
os.close(tmpfile)
print "Downloading to temp file ..."
urllib.urlretrieve(url, tmpfile_path)
#Normally it would try to clean up the file we urlretrieved after this Python
#process ends. Thank BDFL there are no access restrictions on private variables.
urllib._urlopener._URLopener__tempfiles = []

os.execlp(handler, handler, '%s' % tmpfile_path)

#We don't attempt to delete the temporary file because:
# 1. Firefox also doesn't in such cases.
# 2. It's problematic in some instances, such as when the subprocess (this
#     script used to call the handler in a subprocess) finds another copy
#     of itself running, hands the file over to it and exits. Meanwhile, we
#     would be over here deleting the file while the subprocess'es brother
#     hadn't tried to open it yet.

What it does:

  1. Makes a unique filename in the user's Temp directory (same place where Firefox stores files in such cases).

  2. Makes sure that the extension of the temp file will be sane, even with a URL including query strings and hash-anchors (urlretrieve(..) without a second argument handles the former, but not the latter). This is useful, because it tells Vim how to syntax-highlight the file.

  3. Downloads the file from the URL to the current user's Temp directory.

  4. Opens the file with gvim.exe (or an editor of your choice — see below).

How to use this solution:

  1. Save the above Python script as open_with.py somewhere where you keep such scripts.

  2. Install the Open With Firefox extension at the above link and restart Firefox.

  3. Go to Tools > Add-ons > Extensions > Open With > Options. There:

    (a). (Unless you plan to use Open With for its intended purpose, "Hide" all the browsers in the list.)

    (b). "Add..." python.exe.

    (c). Set its "Arguments..." to the path of the script followed by the editor's executable filename or path. For me, this would be
    C:\E\infrastructure\open_with.py gvim.exe

    (d). "Rename..." it to "gVim".

  4. Make sure that gvim.exe is in the PATH variable. I recommend the EditPATH Autohotkey script, which is compilable to an EXE using AHK tools (place it into the Quick Launch folder for convenience — editing PATH becomes three clicks, rather than having to go through the Control Panel memory test yet again.) Otherwise, you must supply the whole path of gvim.exe in step 3(c).

  5. That's it. Now find a link to a file in Firefox, right-click it, and choose "Open Link with gVim".

Screenshot of context menu

(Guess how I got the correct icon there :)

Bonus: if you set the relevant setting in the Open With extension's Options, you can right-click on a Firefox tab and open (most) web pages in Vim too — i.e. like "View Source" except using Vim.

Note that this solution applies just as well to Emacs, Notepad++, and many other software not restricted to text editors. For example, I just tried it with The GIMP, and it opened a PNG file. (To do that, replace gvim.exe above with the path to GIMP. Note: to open an arbitrary image this way, not just a link, you could View Image, and then right-click on its tab.)


Historical note: initially I went for writing a BAT script, but that became untenable after it failed on this test case: http://evgeni.org/w/api.php?format=xml&action=query&titles=AutoHotkey_shortcuts&prop=revisions&rvprop=content
That's because cmd.exe has problems with arguments containing the = character. Furthermore, it was not just a matter of calling gvim.exe with the URL as the command-line argument (though Vim does accept URLs), because it cannot handle this test case — just opens a blank instance of Vim. And for parsing the URL, I'd have to resort to Powershell, which restricts the portability of the solution somewhat. In the end I decided that having an installation of Python as a prerequisite isn't too much to ask.