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
- One of more functions taking no arguments. These are called “hook functions”.
- A variable containing a list of hook functions to call. By convention, this variable’s name ends with
-hook
. - A function,
add-hook
, to add hook functions to the list of hooks. - A function to run the hook functions at the appropriate time.
It turns out there are two main functions to run hooks:
run-mode-hooks
to run hooks associated with a major moderun-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.