Tips on Emacs Lisp programming

I think EmacsLisp is getting to be a great application base, a really good language and environment to write programs in, not just a fancy editor. A number of people seem to agree and are trying it out.

Here's some tips and tricks distilled from my 15 years of using EmacsLisp to help budding Lisp hackers in Emacs.

Do use a modern Emacs

The latest version of Emacs is 24. It's not added to a whole lot of operating system repositories yet but for Debian and Ubuntu you can get it easily by using this repository or PPA at http://emacs.naquadah.org/.

Using the latest version will give you access to lexical scope, built in packaging and lots more goodness.

I am working on a yum equivalent of that APT repository. Donating might make that quicker.

Cut. And also paste

You don't have to have a reusable module for everything, it's ok to cut and paste code sometimes.

There is a massive load of EmacsLisp on github which you can look at and copy.

There's a wealth of code out there, use it

There are Emacs librarys for OAuth (and Oauth2, in ELPA) and for talking to Org Mode and for writing IRC bots or interfacing to PostgreSQL or MySQL or MongoDB. Talking to HTTP and SMTP and handling and parsing XML is built into Emacs. Building parsers and things that understand data definition languages in all sorts of formats is also well covered in EmacsLisp.

Basically, pretty much everything you could want to do as a programmer is there. Sometimes it's not packaged very well, but that's coming.

Use name based namespaces

EmacsLisp does not have a module system. Many people call this a serious weakness but in my experience it's easy to work around it.

There is a heirarchy you should follow:

a package is a file or list of files that may be installed as a package hopefully defined as a package using ELPA standards this is important so you can write code that is portable and has declared dependancies

a module is a file in a package that is provided so it can be required there may be one or many modules in a package

so it can be functions, classes, variables, constants, structs and other top level definitions all exist in a module.

Given this heirarchy we can adopt some simple but consistent rules:

Name classes with a suffix c or C .

or . Name important constants in UPPERCASE.

Use the package name in your module names.

If you have more then one module in your package, then have one top-level module that is the main module of your package, if your package is called somepackage then have a somepackage.el

then have a Use the module name in the names of your functions, variables, methods, classes.

( defun packagename-module-function (args) ...)

or in your top-level module:

( defun packagename-function (args) ...)

Use -- to indicate private variables or functions, like:

( defun packagename--function (args) ...)

macros often need different names, try and use your package and module still, eg this is ok:

( defmacro with-package-module-thing (...) )

Understand packages and autoloads

Autoloads allow lazy loading of EmacsLisp library code. This is basically how they work:

functions or variables marked as ;;;### autoload are compiled into functions that first load the rest of the library and then call the original definition of the function

are compiled into functions that first load the rest of the library and then call the original definition of the function when Emacs starts all the autoloads from all packages are loaded; this is fast because autoloads are very small

when an autoloaded function is called its autoload causes the library to load

Do use CL

Emacs core has always suggested not requiring cl or using:

( eval-when-compile ( require ' cl ))

If you are writing code to go into Emacs then that's still valid, but for your own code? Just require cl , it has so many useful extensions, such as loop and dotimes and merge and lots, lots more.

Do write tests

ERT is included in Emacs 24 and provides a good way of writing tests.

You can even use my fakir library to mock tricky bits of Emacs like processes or files.

It's best to write one module of tests for each module of code. A project with a lot of tests is Elnode. Each test module is named after the module that it tests which seems like more good advice.

Do write function docs

ElDoc is really useful when you're writing EmacsLisp but it only works when you have documentation. Try and write good documentation.

You can use my wikidoc program to make HTML documentation from function and variable doc.

Write command scripts with EmacsLisp

Shell scripts are always quick and easy but sometimes you want a program to do a little more, shell becomes unwieldy fast and you want to switch to a proper programming language. EmacsLisp can do this pretty well, here's an example I've used in my blog before:

: ( require ' cl ) (toggle-debug-on-error) ( defun main () (interactive) ( destructuring-bind (package &optional elpa-parent) command-line-args-left ( when (and elpa-parent (not (file-exists-p elpa-parent))) (make-directory elpa-parent t)) (setq package-user-dir (concat (or (concat elpa-parent "/" ) user-emacs-directory) ".elpa" )) (setq package-archives '(( "gnu" . "http://elpa.gnu.org/packages/" ) ( "marmalade" . "http://marmalade-repo.org/packages/" ))) (package-initialize) (package-refresh-contents) ( if (and (file-exists-p (expand-file-name package)) (not (file-directory-p (expand-file-name package)))) (package-install-file (expand-file-name package)) (package-install (intern package)))))

The first line is what does the magic of making Emacs run the script in batch mode (no windows). Note that what you want to do with the script in that bang line is pretty flexible:

:;exec emacs -batch -Q -l "$0" -f main "$@"

main is the function to call and the $@ is of course shell for the arguments.

Emacs is very powerful at file manipulation, it's buffer mechanism is very useful for certain programming tasks that may be very difficult in shell.

More on scripts in the EmacsWiki.

It's not weird to use Object Orientation in EmacsLisp

Object Oriented coding is suffering a bit of a backlash in some circles but it's still very useful in lots of cicrumstances, where you are trying to declare a category of things that are quite complex for example.

CommonLisp has CLOS, a very comprehensive Object Orientation programming API and EmacsLisp has EIEIO, an implementation of CLOS.

Here's a trivial example of EmacsLisp classes and methods:

( defclass some-userc nil ((id :initarg :id :initform ( lambda () (some-user--make-uuid)) :documentation "The id of the person" ) (name :type string :initarg :name :initform "" :documentation "Name of the person" )) "A user record." ) ( defun some-user--make-uuid () "1213243" ) ( defmethod some-user-greeting ((user some-userc) &optional daytime) "Methods are functions and have docstrings." ( if daytime (message "good morning %s" (oref user name)))) ( let ((user (some-userc "nic" :name "nic ferrier" ))) (some-user-greeting user t))

Macro writing needs settings

eval-expression-print-level needs to be set to nil (turned off) so that you can always see what's happening.

Don't write too many macros

Macro use cases are:

hiding access to resources

building DSLs

and abstracting control flow

Of these only the first is common in most programming, the second is obvious when you need it and the last you should think quite carefully before doing, it's normally for Lisp language hackers, not hackers in Lisp language.

PS That doesn't mean you should never write control flow macros, just think hard before doing it.

Closures are cool but harder to debug

If you need anything more than a tiny callback function then make a tiny callback that calls an external function with the right data:

( let ((x somecapturedthing)) ( lambda (httpcon) (real--implementation httpcon x)))

The full function is nearly always private but it can be more easily instrumented for debugging so you can easily see what's going on in that code. It's also useful sometimes to separate stuff out like this temporarily. It's pretty easy to do quickly, it's probably easy enough that you could write some EmacsLisp to do it automatically.

Use the manuals

Emacs has great documentation including about EmacsLisp itself and CL and EIEIO.

The Elisp Cookbook on the EmacsWiki is also a great resource.

Do ask questions

On StackOverflow, reddit or on IRC.

So that's it

These are the things I can think of that people don't know. If you're thinking of looking at a Lisp for your next programming project then I really recommend EmacsLisp, it's a very practical language with lots to recommend it.

Fixes