Archives / Search ›

Emacs 21.1 for Mac OS X is a great port; I've been using it for a few months. Like everything else on Mac OS X, it suffers from glacial startup speed. If you have a lot of RAM, the best solution I've found is to leave frequently-used programs open all the time.

Then you need some way of communicating with those programs from the command line. My launch tool is a help for most applications, and some, such as BBEdit, provide their own command-line tools with additional functionality.

But Emacs isn't really a Mac app, so it doesn't respond to Apple Events. You can't drop files on top of it or use launch.

One alternative is to live in Emacs, so finding a file is always a keystroke away, but I don't work that way. Another is to run a server inside Emacs, which you can ask to open files and execute commands. You can run this server with (server-start) in GNU Emacs, or (gnuserv-start) in XEmacs. No, I didn't get those commands mixed up, the usual convoluted heritage of the programs is responsible.

Next up are the client-side programs: XEmacs has 'gnuclient', and GNU Emacs has 'emacsclient'. Much like BBEdit's command-line bbedit tool, these behave like an editor, in that they take command-line arguments of files, but instead of opening a new Emacs process, they instruct the already-running Emacs to open the files.

With Carbon Emacs, emacsclient does not cause Emacs to come to the front, and you can't pass command-line arguments to the Carbon Emacs when it's running in a window. On any platform, emacsclient gives an error message if Emacs is not yet running. By default, emacsclient pauses until the editor exits: good for using Emacs as an external editor, but not so good when calling it directly from the command line.

So, I wrote a quick script to make emacsclient like bbedit. First, make sure you include (server-start) in your .emacs file or equivalent. Then put this alias in your .zshrc file, or adapt it for tcsh/bash/scsh/whatever you use.

if [[ ! -z $TERM_PROGRAM ]] {
  e() {
    ( emacsclient -n $@ >&/dev/null && \
      osascript -e 'tell application "Emacs" to activate' ) || \
    ( launch -a Emacs && sleep 2 && emacsclient -n $@ )
  }
}

If $TERM_PROGRAM is set (you're running inside Terminal), this script creates an alias called e which tries to invoke emacsclient with the -n option (don't wait around) and bring Emacs to the front. If that fails, Emacs is probably not running, so it opens Emacs, waits a couple of seconds for Emacs to finish launching (if you have a slower machine you may need to change the number 2 to something bigger), then invokes emacsclient.

Comments are closed.