el-get

Emacs Lisp get (Fetch, Install, Update, etc)

El-get is tool that allows downloading external scripts/extensions for Emacs, install them for you, knows how to update them and init them, care about load-path and Info-directory-list, byte-compile what should be, manages autoloads, etc.

JohnWiegley once said “el-get seems like it’s the Great Unifier of Emacs package systems and package repositories”

Think apt-get for Emacs, and check out el-get.

Why el-get?

Of course, my emacs setup is managed in a private git repository. Some people on #emacs are using git submodules (or was it straight import) for managing external repositories in there, but all I can say is that I frown on this idea. I want an easy canonical list of packages I depend on to run Emacs, and I want this documentation to be usable as-is. Enters el-get!

How is el-get different from ELPA?

ELPA is the Emacs Lisp Package Archive and is also known as package.el, to be included in Emacs 24. This allows emacs list extension authors to package their work. That means they have to follow some guidelines and format their contribution, then propose it for upload.

This requires licence checks (good) and for the new official ELPA mirror it even requires dead-tree papers exchange and contracts and copyright assignments, I believe.

Why have both?

While ELPA is a great thing to have, it’s so easy to find some high quality Emacs extension out there that are not part of the offer. Either authors are not interrested into uploading to ELPA, or they don’t know how to properly package for it (it’s only simple for single file extensions, see).

So el-get is a pragmatic answer here. It’s there because it so happens that I don’t depend only on emacs extensions that are available with Emacs itself, in my distribution site-lisp and in ELPA. I need some more, and I don’t need it to be complex to find it, fetch it, init it and use it.

Of course I could try and package any extension I find I need and submit it to ELPA, but really, to do that nicely I’d need to contact the extension author (upstream) for him to accept my patch, and then consider a fork.

What about MELPA?

MELPA has been described as “server-side el-get”. Since all the fetching is done on the server it does offer some more convenience. However, it also takes away control: MELPA only offers the latest version of the package, whereas el-get can get any revision you want, or even use a different fork. Since el-get uses package.el as one of the fetching methods, MELPA’s convenience is still available.

In addition, el-get also offers more local initialization features than MELPA. For example, some packages have some C program dependencies that el-get can auto build but MELPA does not and will not handle.

Example Usage

The following is an example of how to use it in your .emacs, you could also consider starting from the emacs-kicker.

(add-to-list 'load-path "~/.emacs.d/el-get/el-get")

(unless (require 'el-get nil t)
  (url-retrieve
   "https://github.com/dimitri/el-get/raw/master/el-get-install.el"
   (lambda (s)
     (end-of-buffer)
     (eval-print-last-sexp))))

;; now either el-get is `require'd already, or have been `load'ed by the
;; el-get installer.

;; set local recipes, el-get-sources should only accept PLIST element
(setq
 el-get-sources
 '((:name buffer-move			; have to add your own keys
	  :after (progn
		   (global-set-key (kbd "<C-S-up>")     'buf-move-up)
		   (global-set-key (kbd "<C-S-down>")   'buf-move-down)
		   (global-set-key (kbd "<C-S-left>")   'buf-move-left)
		   (global-set-key (kbd "<C-S-right>")  'buf-move-right)))

   (:name smex				; a better (ido like) M-x
	  :after (progn
		   (setq smex-save-file "~/.emacs.d/.smex-items")
		   (global-set-key (kbd "M-x") 'smex)
		   (global-set-key (kbd "M-X") 'smex-major-mode-commands)))

   (:name magit				; git meet emacs, and a binding
	  :after (progn
		   (global-set-key (kbd "C-x C-z") 'magit-status)))

   (:name goto-last-change		; move pointer back to last change
	  :after (progn
		   ;; when using AZERTY keyboard, consider C-x C-_
		   (global-set-key (kbd "C-x C-/") 'goto-last-change)))))

;; now set our own packages
(setq
 my:el-get-packages
 '(el-get				; el-get is self-hosting
   escreen            			; screen for emacs, C-\ C-h
   php-mode-improved			; if you're into php...
   switch-window			; takes over C-x o
   auto-complete			; complete as you type with overlays
   zencoding-mode			; http://www.emacswiki.org/emacs/ZenCoding
   color-theme		                ; nice looking emacs
   color-theme-tango))	                ; check out color-theme-solarized

;
;; Some recipes require extra tools to be installed
;;
;; Note: el-get-install requires git, so we know we have at least that.
;;
(when (el-get-executable-find "cvs")
  (add-to-list 'my:el-get-packages 'emacs-goodies-el)) ; the debian addons for emacs

(when (el-get-executable-find "svn")
  (loop for p in '(psvn    		; M-x svn-status
		   yasnippet		; powerful snippet mode
		   )
	do (add-to-list 'my:el-get-packages p)))

(setq my:el-get-packages
      (append my:el-get-packages
              (mapcar #'el-get-source-name el-get-sources)))

;; install new packages and init already installed packages
(el-get 'sync my:el-get-packages)

So now you have a pretty good documentation of the packages you want installed, where to get them, and how to install them. For the advanced methods (such as ELPA or apt-get), you basically just need the package name. When relying on a bare git repository, you need to give some more information, such as the URL to clone and the build steps if any. Then also what features to require and maybe where to find the texinfo documentation of the package, for automatic inclusion into your local Info menu.

The good news is that not only you now have a solid readable description of all that in a central place, but this very description is all (el-get) needs to do its magic. This command will check that each and every package is installed on your system (in el-get-dir) and if that’s not the case, it will actually install it. Then, it will init the packages: that means caring about the load-path, the Info-directory-list (and dir texinfo menu building) the loading of the EmacsLisp files, and finally it will require the features.

Social Packaging

With el-get I propose distributed packaging if you will. Let’s have a look at two recipes here. First, the el-get one itself:

(:name el-get
       :type git
       :url "git://github.com/dimitri/el-get.git"
       :features el-get
       :compile "el-get.el")

Then a much more complex one, the bbdb one:

(:name bbdb
       :type git
       :url "git://github.com/barak/BBDB.git"
       :load-path ("./lisp" "./bits")
       :build ("./configure" "make autoloads" "make")
       :build/darwin ("./configure --with-emacs=/Applications/Emacs.app/Contents/MacOS/Emacs" "make autoloads" "make")
       :features bbdb
       :after (lambda () (bbdb-initialize))
       :info "texinfo")

The idea is that it’s much simpler to just come up with a recipe like this than to patch existing code and upload it to ELPA. And anybody can share their recipes very easily, with or without proposing them to me, even if I very much like to add some more in the official el-get list.

As a user, you don’t even need to twiddle with recipes, mostly, because we already have them for you. What you do instead is list them in el-get-sources.

el-get and emacswiki

Just run M-x el-get-emacswiki-refresh and you will have a local cache of recipes for all scripts available in EmacsWiki. Now you can M-x el-get-install any of them, it’s a single command away.

emacs-kicker

Following up on the very popular emacs-starter-kit, I’m now proposing the emacs-kicker. It’s about a very simple .emacs file using el-get. It comes with an arbitrary selection of packages that make your life easier, and with some medium advanced settings. The idea is to, well, kick start you.

If you want to try it without installing it it’s very easy to do so. Just clone the git repository then start an Emacs that will use this. For example that could be, using the excellent Emacs For MacOSX:

$ /Applications/Emacs.app/Contents/MacOS/Emacs -Q -l init.el 

CategoryPackaging