Updating el-get and getelget.el
Last week one of my Emacs using colleagues asked me how I managed my Emacs
packages and configuration. Naturally I pointed him to el-get and my
getelget.el bootstrap script. I’ve been happily managing my Emacs
installation over the past five months using el-get and a private git repository
for my configuration. However when I tried to square my .emacs.d/init.el
with
the current el-get documentation, I got a little confused; el-get is now better
at bootstrapping itself from within your Emacs configuration. When my colleague
read this and asked why he might want getelget.el
, my response was… well,
lackluster; this is an attempt to document that a littler better.)
Last night I decided to do a little clean-up on my Emacs configuration, and see
if I could get rid of getelget.el. The documentation for el-get is great,
so I started there. What I quickly realized is that the included el-get
bootstrap mechanism is great if you want to ensure el-get is installed and then
use el-get-install
, el-get-remove
, etc to manage your packages. But if you
define your package list in you config file, it’s not quite enough.
Specifically, when you first bootstrap your configuration, you want to defer
calling (elget 'sync)
until you’ve bootstrapped el-get. And on future runs,
you want to go ahead and install any new packages that have been added to your
list.
Luckily el-get has added support for hooks, which makes life a little easier.
The new getelget.el
(available here) looks something like this:
;; getelget – el-get boostrap script
;;
;; Checks to see if el-get has been checked out, and bootstraps it if
;; it has not. After bootstrapping, calls el-get to load specified;; packages.
;;
;; el-get-packages should be defined before including this file. Any
;; definitions from el-get-sources will be appended to el-get-packages.
;;
;; Written in 2011 by Nathan R. Yergler
;;
;; To the extent possible under law, the person who associated CC0 with
;; getelget has waived all copyright and related or neighboring rights
;; to getelget.
;;
;; You should have received a copy of the CC0 legalcode along with this
;; work.
;; add a hook listener for post-install el-get(defun post-install-hook (pkg)
;; after installing el-get, load the local package list
(if (string-equal pkg “el-get”)
(el-get 'sync
(append el-get-packages
(mapcar 'el-get-source-name el-get-sources)))))(add-hook 'el-get-post-install-hooks 'post-install-hook)
;; add the el-get directory to the load path(add-to-list 'load-path
(concat (file-name-as-directory user-emacs-directory)
(file-name-as-directory “el-get”)
“el-get”))
;; try to require el-get(if (eq (require 'el-get nil t) nil)
;; urp, need to bootstrap
(url-retrieve
“https://raw.github.com/dimitri/el-get/master/el-get-install.el”
(lambda (s)
(end-of-buffer)
(eval-print-last-sexp)))
;; successfully required el-get, load the packages!
(post-install-hook “el-get”)
el-get also recommends splitting your package definitions from your local
source recipes (which can themselves extend an included recipe). So getelget.el
now expects you’ve defined two lists: el-get-packages
, a list of packages to
install from recipes, and el-get-sources
, your local source list.
For example, I define a local recipe for magit that binds a key to
magit-status
and enables spell checking and fill mode for commit message
editing:
(setq el-get-sources
'((:name magit
:after (lambda ()
(global-set-key “\C-x\r\r” 'magit-status)
;; Enable spell checking, fill for log editing
(add-hook 'magit-log-edit-mode-hook
(lambda()
(auto-fill-mode 1)
(flyspell-mode 1)))))
))
And my el-get-packages
list is just a list of packages I’m installing from the included el-get recipes.
(setq el-get-packages
'(el-get
google-maps
color-theme
python-mode
virtualenv
php-mode-improved
xml-rpc-el
js2-mode
org2blog))
Everything listed in both lists will be installed.
YMMV, FWIW, ZOMG, BBQ, etc.