os x emacs and gnuserv
As part of my final migration to all things Macintosh, I needed to get my text editing situation under control.
After developing on various X windows based platforms for the vast bulk of my career, I’m very comfortable with using the command line to navigate around a programming project. My work pattern is typically to move around on the command line until I need to edit a file. Then I have a command line tool that will bring that file up in my chosen editor. Users of BBEdit on Mac OS X might be familiar with this, as BBEdit includes a nice command line utility that you can use for this. If push came to shove, I could probably live with using BBEdit as my main editor.
However, for many years, I’ve been using a shell script wrapper around “gnuclient”, which would bring up an (X)Emacs frame with my file. Very very convenient. This was a practice started in the distant past when I used both XEmacs instead of (GNU) Emacs, and it took forever to launch a new instance of XEmacs (as well as each instance sucking up a lot of memory). In any case, I wanted to stick with Emacs because 15 years of using it has so deeply ingrained the key combinations that I try and turn on emacs-like key bindings wherever I go. Not that BBEdit is a bad editor, but when you’ve invested in Emacs as much as I have, you tend to want to stick with it for most things. (I do find BBEdit to be a much better option when dealing with HTML and CSS, however).
So, first off was to get a build of Carbon Emacs. I had played with Aquamacs, which is essentially a different build of Carbon Emacs, but it want’s to use ESC as meta by default, and that doesn’t work for me.
I had originally tried Aquamacs because my original copy of Carbon Emacs was locked into a particular, weird install location. The current version of Carbon Emacs doesn’t seem to have that restriction, and seems to be quite nice, actually.
Next, was to get gnuserv/gnuclient working. Interestingly enough, OS X 10.4 (and possibly earlier? I haven’t checked) comes with gnuserv and gnuclient already installed, presumably for use with the terminal-based emacs that it ships with (and it works!). Getting it to work with Carbon Emacs was just the trick I was looking for. Based on previous work, I had downloaded an external gnuserv implementation.
Version 3.12.6 didn’t compile cleanly on 10.4, but 3.12.7 did. I don’t
think that you need to do this at all, however. Mostly what you need
is to give Carbon Emacs access to three elisp files from that gnuserv
distribution – which are already in your Tiger system in
/usr/share/emacs/21.2/lisp directory. The three files are
devices.el. You could
probably just throw them into your Carbon Emacs’s internal lisp
directory, or you can do what I did–put them somewhere in your home
directory and get .emacs to point to them. Something like:
(setq load-path (cons (expand-file-name "\~/.fsfemacs/pkg/gnuserv") load-path))
which assumes that you put them into the ~/.fsfemacs/pkg/gnuserv directory. Modify that to match wherever you put them. Next, put
somewhere in you .emacs. This will actually cause your Carbon Emacs to run gnuserv in a sub-process.
One potential problem remains, however. If you have DISPLAY set in the environment that Carbon Emacs in running it (like I do), using gnuclient will generate an error message, rather than actually work. What is going on is that Carbon Emacs cannot actually connect to an X display (not actually being an X application). There are probably a number of different ways to fix this. How I did it was to patch devices.el:
--- devices.el 2000-01-31 18:12:32.000000000 -0500 +++ devices.el.davidb 2005-06-03 11:09:03.000000000 -0400 @@ -69,7 +69,8 @@ have no effect." (cond ((and (eq type 'x) connection) - (make-frame-on-display connection props)) + ; (make-frame-on-display connection props)) + (make-frame props)) ((eq type 'x) (make-frame props)) ((eq type 'tty)
Oh, and a helpful hint for any folks (like me) who traditionally defined a lot of binding to function keys: in Carbon Emacs, option+function key seems to register as the function key, and bypasses any OS-level bindings.