Monday, November 8, 2010

Setting up Emacs.app

I use OS X at both work and home, and I'm a dedicated GNU Emacs user. There are several ways to run GNU Emacs under OS X, but I like Emacs.app (or GNU Emacs/Cocoa or GNU Emacs/nextstep if you prefer). This means Emacs runs just like a normal OS X application and is fully integrated into the Finder. This has one little annoyance though. If you have installed other command line utilities in places other than /usr/bin, /bin, /usr/sbin or /sbin Emacs.app can't find them. Why you ask? Because by default that is what the Finder sets your PATH environment variable to be. So there are two ways to fix this.

Add new paths to the Finder

This is pretty easy. Just follow the directions here: http://developer.apple.com/library/mac/#qa/qa2001/qa1067.html

You will probably want to add paths for: PATH, MANPATH and INFOPATH

The downside of this approach is now you have set the environment variable for every application that is run from the Finder. That may or may not be what you want. Also you have to force the Finder to re-read the plist file every time you want to make a change. That usually means logging out and back in.

Add paths to Emacs.app

So Emacs has some internal variables that it uses to track these paths. We can just modify them in Emacs itself, and tweak them whenever we want to.

Finding new executables

Emacs uses the exec-path variable to find any additional utilities it needs. Here is some example code for how to add paths to the exec-path variable.

;;; Add directories to exec-path
(mapcar '(lambda (x)
           (add-to-list 'exec-path x))
        '("/usr/local/bin"
          "/opt/local/sbin"
          "/opt/local/bin"
          "~/bin"))

If you run shells inside of Emacs, you may want to modify the PATH variable as well. Why? Well if you run a shell inside Emacs it will use the PATH variable to find things not the exec-path variable. Here is some example code for that:

;;; Setup PATH variable
(mapcar (lambda (x)
          (setenv "PATH"
                  (concat x ":" (getenv "PATH"))))
        '("/usr/local/bin"
          "/opt/local/sbin"
          "/opt/local/bin"
          "~/bin"))

Finding new man pages

Emacs.app uses the MANPATH variable to find manpages, here is some example code on how to modify it:

;;; Setup MANPATH variable
(mapcar (lambda (x)
          (setenv "MANPATH"
                  (concat x ":" (getenv "MANPATH"))))
        '("/opt/local/man"
          "~/man"))

Finding new info pages

Emacs.app uses the Info-directory-list variable to find info pages. Here is some example code:

;;; Setup info path
(require 'info)
(mapcar '(lambda (x)
           (add-to-list 'Info-directory-list x))
        '("/usr/share/info"
          "/opt/local/share/info"
          "/Applications/Emacs.app/Contents/Resources/info"
          "~/info"))

This one is a little trickier than the others. First you have to load the info package so that the Info-directory-list is defined. Then you should also add the info directory from the Emacs.app itself.