Technology and Software

emacs:// URLs in Ubuntu

I’ve been experimenting with the better_errors gem and I discovered that vim handles mvim:// urls. That’s nice because the gem turns the file name in the error message into a URL that opens the file in the editor at the line of the error. I’m an emacs user and want to have the same feature. I use Ubuntu with Gnome so my solution works in that desktop environment.

I got three browsers on Ubuntu: Firefox, Chrome, Opera. They must handle URLs like @emacs://+20 ~/.bashrc@.

If we prompt Firefox with that URL it will ask us to associate a program to it so we only need to create a bash script that extracts the line number and the file name from the URL and passes them as arguments to emacsclient.

Chrome uses xdg-open, which needs a .desktop file that describes which program to run.

Opera must be configured: Edit preferences, Advanced, Programs, Add… and then Protocol: emacs, Open with other application: the path to the program.

This is the program that calls emacsclient:


args=`echo $* | sed -e "s/^emacs:\/\/+\([0-9]\+\)\(.*\)$/+\1 \2/" -e 's/%20/ /g'`
line=`echo $args | cut -f1 -d" "`
file=`echo $args | cut -f2- -d" "`
/usr/bin/emacsclient.emacs-snapshot -n $line "$file"

Put it somewhere in PATH, maybe ~/bin/emacsclient-url, and make it executable.

Open @emacs://+20 ~/.bashrc@ in Firefox and associate it to the program. Check that it opens the file in emacs (emacs must be already open). Check that URL in Opera too. Chrome’s turn now.

The .desktop file for xdg-open must be located in the /usr/share/applications/ directory. Let’s call it emacs-client-snapshot.desktop

[Desktop Entry]
Name=Emacs Client Snapshot (GTK)
Comment=GNU Emacs Client Snapshot Text Editor
Exec=/path/to/emacsclient-url %u

Run sudo update-desktop-database and test with xdg-open “emacs://+6 ~/.bashrc”. Check that the URL opens in Chrome too.

Finally, to use those URLs in better_errors we must add this line to our code, possibly a Rails initializer.

BetterErrors.editor ={|file, line| "emacs://+#{line} #{file}"}

Be sure to try that gem.