Emacs Hooks

Daniel Liden has a useful post on elementary hook functions. From the (Elisp) user perspective, there’s not a lot to know. All you need is

  1. One of more functions taking no arguments. These are called “hook functions”.
  2. A variable containing a list of hook functions to call. By convention, this variable’s name ends with -hook.
  3. A function, add-hook, to add hook functions to the list of hooks.
  4. A function to run the hook functions at the appropriate time.

It turns out there are two main functions to run hooks:

  1. run-mode-hooks to run hooks associated with a major mode
  2. run-hooks to run hooks not associated with modes

The existence of a special function for mode hooks raises an obvious question: “Why do we need a special function for mode hooks?” I didn’t know so of course I had to see how they differ. Run-mode-hooks is more complicated and basically takes care of worrying about doing the right thing when it’s called from a derived mode. Complicated but not too exciting.

One surprising fact that I discovered is that run-hooks is a builtin function in the C core. I always imagined that run-hooks was a simple function along the lines of

(defun run-hooks (hooks)
  (dolist (h hooks)
    (funcall h)))

The C version does essentially the same thing except that the list of functions can also contain a sublist of functions. Here it is (with the doc string removed):

DEFUN ("run-hooks", Frun_hooks, Srun_hooks, 0, MANY, 0,
  (ptrdiff_t nargs, Lisp_Object *args)
{
  ptrdiff_t i;

  for (i = 0; i < nargs; i++)
    run_hook (args[i]);

  return Qnil;
}

It could hardly be simpler so why is it in the C core? My guess is because it’s needed before the rest of the Lisp run time is established although I’m having a hard time making sense of that. If anyone knows for sure, leave a comment.

This entry was posted in General and tagged . Bookmark the permalink.