Andreas Jacobsen's Distraction

Another cause of procrastination

ELisp best practices?

with 3 comments

I’ve spent some time looking at Emacs Lisp lately and there’s a weird ecosystem going on there. ELisp (and I’m thinking primarily about Emacs configuration here) tends to grow organically, because it’s paced by a person’s learning of the editor. Every now and then someone needs a new function, and they either search or ask around for something similar. Either it’s been implemented before and the code can be copied into their local Emacs configuration or they can write a simple version that is sufficient for initial usage.

The way I tend to grow my Emacs is either piecemeal, as described above, or by reading other people’s code. Sharing Emacs configuration code is a long tradition, and there are many webpages dedicated to it (DotEmacs, there are plenty on the Emacs wiki and ELisp is the 11th most used language on GitHub). Reading someone else’s Emacs configuration is a great way to get new ideas. Recently I’ve found djcb’s dotemacs (he also runs an interesting blog called emacs-fu) and the emacs starter kit very interesting.

In particular, I noted two things. In djcb’s dotemacs, he defines macros for conditional requires, that degenerate gracefully when required libraries are unavailable, instead of erroring. It similarly has a macro when-available, that runs some code if and only if a given function is available. These are used liberally throughout his configuration, making it robust against unexpected environmental differences. When I first saw this I considered it clever (and still do, really) and wondered whether I should include something similar in my Emacs configuration. In the end I decided against it, because I only use Emacs in very similar versions on two machines and version control libraries that are missing from either or both systems. This ensures that I rarely see errors from missing requires or functions.

In emacs-starter-kit the use of ELPA, the Emacs Lisp Package Archive, intrigued me. I’m a big fan of package management, though I tend to be of the ‘one package manager to rule them all (per system)’ crowd. Using ELPA instead of (re-)versioning all the external code I use seems like a good idea, though I’ve put it off for a bit due to the number of comments to the effect of ‘workaround for bug in ELPA’ in the starter kit. I’d also like a web interface to browse available packages and accompanying source so I can check on the status of all the libraries I already use.

Thinking about both these things, gracefully accepting the limitations of environment and package management for dependency resolution, I started to wonder about other best practices for ELisp. While Emacs is a huge framework in and of itself, the incremental improvement pattern for building ELisp doesn’t exactly invite to build other frameworks. So I wasn’t very surprised when I found that the only unit testing framework is quite new and not generally accepted as the right way to test ELisp (discussion here).

None of the advice or ideas I’ve found have really addressed the practice of writing ELisp, maybe with the exception of Steve Yegge’s save-excursion post. Even people who talk about modularity don’t generally mention how to best organize ELisp modularly. This isn’t necessarily bad. The lack of clear practices does mean one has to make a lot of judgement calls on what the right thing to do at any given point is, taking into account the one’s own requirements and limitations.

About these ads

Written by Andreas

January 7, 2009 at 20:57

Posted in Editors

Tagged with ,

3 Responses

Subscribe to comments with RSS.

  1. I have another way of doing it that may be more modular. When I want to use a new package, I make a new file ~/.emacs.d/me-package.el I put (require ‘package) in me-package.el, along with any customizations for the package that I want. I then use autoload in my ~/.emacs to load me-package whenever I use one of the commands that the package provides.

    For example, I just started using ack instead of grep. I put

    (require ‘ack)

    (setq ack-guess-type t)
    (setq ack-command “ack-grep –nocolor –nogroup”)

    (provide ‘me-ack)

    in ~/.emacs.d/me-ack and

    (autoload ‘ack “me-ack” “grep replacement” t)

    in ~/.emacs

    I think the advantage of this is to separate the configuration of different packages, while not dying if one of the packages isn’t present. It should also speed up initial loading time a little bit because large packages aren’t loaded until they are needed.

    Chris

    January 8, 2009 at 14:59

  2. That’s interesting. I think autoload is next up on the list of things to add for my config. I did something similar previously, having a custom package of my own to require so I could gather any customizations there. I cut down on it when I realized I had a bunch of these where the only thing they did was require the original package.

    Andreas

    January 8, 2009 at 16:04

  3. [...] one page wondering the same thing. There’s always a ton of interesting stuff whenever you go poking at emacs packages; most [...]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: