Using "Open with" Emacs on a Mac
Sunday, February 25, 2007
Ok, I'll admit it - I'm an Emacs fanboy. ;-) I don't like the default application that is standard for many document types on the Mac, so I have the default switched over to emacsclient for a lot of file types so that they are opened in my running instance of Emacs instead of textedit or some other app. However, there are some problems with this approach (Note: see the update at the bottom of this post as the following is not correct):
- There are some file types that I prefer to leave with a different default but I still want to sometimes open them with Emacs. The Finder "Open With" functionality only works with ".app" objects, not conventional executables. So, although I could open them with Emacs, this would launch a new instance of Emacs and not send them to a running instance of Emacs (which is what emacsclient does).
- Although I usually have an instance of Emacs running, I don't always have one open. The emacsclient program won't open Emacs if it isn't already running, so if the default app for a file type is emacsclient, you need to have an instance of Emacs running or the file won't be opened when you double-click on it.
First of all, a caveat: I tend to use the Aquamacs Emacs emacs build on Mac OS X and am really happy with it. It provides the right mixture of Emacs and Mac-specific functionality. I also build a standard Emacs from CVS so the version of emacsclient that is in my "/usr/local/bin/" directory is the same as the one that is located in "/Applications/Aquamacs Emacs.app/Contents/MacOS/bin/". So, what I outline below is customized to work with my particular Aquamacs; however, it should also work with any other CVS-based Emacs build on Mac OS X once you adjust the directory locations in the following script to point to compatible versions of emacsclient and emacs.
Basically, all I did was take Drew's tip and expand it to cater for the other scenarios; so, to replicate what I did:
- Download Platypus - it's a little utility that lets one create a ".app" wrapper around a script.
- Create the following "emacsclient.sh" bash script to either call emacsclient (if Emacs is
already running) or Emacs itself (if it isn't running):
#!/bin/sh /usr/local/bin/emacsclient -n "${2}" 2> /dev/null if [ $? -ne 0 ]; then open -a /Applications/Aquamacs\ Emacs.app "${2}" fi - Make certain that you remember to chmod the "emacsclient.sh" script so that it is executable
- Make certain that your ".emacs" file has "server-start" in it so that emacsclient can connect to a running Emacs instance
- Run Platypus and create a ".app" wrapper for the "emacsclient.sh" script, saving the result as "emacsclient.app" (be sure that the "Is droppable" property is turned on in Platypus) in your "Applications" folder:

That's it! Now, you'll have an "emacsclient.app" application that you can send any object to (by right-clicking on the object in Finder and selecting emacsclient.app as the application to use on the "Open With" menu). And, for those objects that you want to open in Emacs all the time, you can change the default "Open With" application for those objects so that they are opened by default with emacsclient.app. And, since the emacsclient.sh script checks to see whether Emacs is running first, you will always get Emacs to open your file regardless of whether there is a running instance of Emacs or not.
A "side benefit" of this approach is that (so long as you have built CVS Emacs as well as Aquamacs Emacs so that you have a compatible version of Emacs/emacsclient) it will also work with a terminal-based version of Emacs. So, if I have open an instance of Emacs in a terminal, the selected file will be opened in that instance of Emacs (instead of opening a new instance of Aquamacs Emacs). Since I sometimes do like to use a terminal-based emacs, this is quite convenient.
Update-2007-02-26: David Reitter (the primary developer of the Aquamacs Emacs distribution) emailed me to say that I shouldn't need to use the emacsclient.app approach since OS X won't run the same application twice. However, I was sometimes getting multiple instances of Aquamacs (hence the emacsclient.app approach)! After some investigation, it turned out that I had another development copy of Aquamacs in a different directory and that copy was sometimes being run instead of the one in "/Applications". Once I deleted the copy, everything opened properly in the single instance of Aquamacs. I can set the default application to Aquamacs and use "Open With" Aquamacs (for objects that don't have Aquamacs as the default) and everything works fine. So, you can basically ignore almost everything I said in this article! My apologies for any confusion this might have caused. :-(
Update-2008-05-11: Anthony Yen pointed out to be that the bash script (as I had written it) did not cater for file names with embedded spaces. I have corrected the above bash script as per Anthony's suggestion.

