This article essentially describes the top of my Emacs init file. That part of the code is devoted to modify the session bootstrap process, that is, some things that are normally done very early. It mostly deals with the package infrastructure but also contains a couple of other tricks that some people may consider useful. It goes like this…
The first line is self-explanatory (and please, be warned that I will discard any comment about it. You know why).
A self-contained Emacs.app on MacOS X has its own
site-lisp directory, but I want to make sure that the standard Unix one is here as well, and takes precedence.
(when (featurep 'ns)
(add-to-list 'load-path "/usr/local/share/emacs/site-lisp"))
When not starting Emacs from the command-line (e.g. MacOS X app clicks or Quicksilver, Unitiy launcher on Ubuntu etc.), I don't necessarily get my environment-based exec-path so I need to restore it. Note that this trick works because the standard value is (I think) computed when Emacs is built, and I happen to build it myself, in my own environment.
(let ((standard-exec-path (cadar (get 'exec-path 'standard-value))))
(mapc (lambda (path) (setq exec-path (remove path exec-path)))
(setq exec-path (append standard-exec-path exec-path)))
Initialize ELPA now so that the rest of the initialization process may rely on packages without having to go through
I want system-wide directories to be named
emacs-packages instead of
(dolist (path load-path)
(and (stringp path)
(equal (file-name-nondirectory path) "site-lisp")
(push (expand-file-name "emacs-packages"
I want my local directory to follow the same convention.
(setq package-user-dir "~/.emacs.d/emacs-packages")
Now, it's okay to initialize ELPA.
Now that the packages have been initialized, I actually want ELPA to install in
/usr/local/share/emacs/emacs-packages by default, and keep my local directory for manual installations. One simple way to achieve that is to set my local directory to
/usr/local/share/emacs/emacs-packages and to remove that from the system-wide directory list. One small drawback of this is that my local path is gone, so any new package installed there won't be seen until the next restart. This is not much of a problem though.
(setq package-user-dir "/usr/local/share/emacs/emacs-packages"
package-directory-list (remove "/usr/local/share/emacs/emacs-packages"
Site and local (non ELPA) packages infrastructure
The purpose of this other infrastructure is to support packages that would be installed manually, outside ELPA, and in a way similar to XEmacs packages. A packages directory has
info/ subdirectories. Every package installs its stuff directly in
info/, but adds its own subdirectory to
lisp/ and puts its code (including a potential autoloads file) in there.
This additional infrastructure comes in handy in several situations. For instance, having Slime (auto)loaded in your session now becomes as simple as this:
ln -s /path/to/slime /usr/local/share/emacs/local-packages/lisp/
(defun dvl-initialize-packages (directory)
"Initialize non-ELPA packages DIRECTORY.
- adding the whole lisp/ subtree to LOAD-PATH,
- loading the autoload files found there.
- adding DIRECTORY to INFO-DEFAULT-DIRECTORY-LIST."
(let ((default-directory (expand-file-name "lisp" directory)))
;; 1. Update LOAD-PATH
(let ((load-path (copy-sequence load-path)))
(append (copy-sequence (normal-top-level-add-to-load-path '(".")))
;; 2. Load autoload files
(loop for directory in load-path
while (string-prefix-p default-directory directory)
do (mapc #'load (directory-files directory t "-autoloads\\.el$"))))
;; 3. Update the default Info directory list
(expand-file-name "info" directory)))
Be sure to do this by increasing priority order.
And now we can re-initialize Info with the proper defaults.
(setq Info-directory-list nil)
Now that we have bootstrapped the complete packages infrastructure, we can set the Custom file to something that makes sense and load it now.
(setq custom-file "~/.emacs.d/custom.el")
Finally, install the rc files loader and we're done bootstrapping.
That completes my session bootstrap process.