57.3.2 Hooks

Hooks are an important mechanism for customizing Emacs. A hook is a Lisp variable which holds a list of functions, to be called on some well-defined occasion. (This is called running the hook.) The individual functions in the list are called the hook functions of the hook. With rare exceptions, hooks in Emacs are empty when Emacs starts up, so the only hook functions in any given hook are the ones you explicitly put there as customization.

Most major modes run one or more mode hooks as the last step of initialization. This makes it easy for you to customize the behavior of the mode, by setting up a hook function to override the local variable assignments already made by the mode. But hooks are also used in other contexts. For example, the hook kill-emacs-hook runs just before quitting the Emacs job (see Exiting).

Most Emacs hooks are normal hooks. This means that running the hook operates by calling all the hook functions, unconditionally, with no arguments. We have made an effort to keep most hooks normal so that you can use them in a uniform way. Every variable in Emacs whose name ends in ‘-hook’ is a normal hook.

There are also a few abnormal hooks. These variables' names end in ‘-hooks’ or ‘-functions’, instead of ‘-hook’. What makes these hooks abnormal is that there is something peculiar about the way its functions are called—perhaps they are given arguments, or perhaps the values they return are used in some way. For example, find-file-not-found-functions (see Visiting) is abnormal because as soon as one hook function returns a non-nil value, the rest are not called at all. The documentation of each abnormal hook variable explains in detail what is peculiar about it.

You can set a hook variable with setq like any other Lisp variable, but the recommended way to add a hook function to a hook (either normal or abnormal) is by calling add-hook. See Hooks.

For example, here's how to set up a hook to turn on Auto Fill mode when entering Text mode and other modes based on Text mode:

     (add-hook 'text-mode-hook 'turn-on-auto-fill)

The next example shows how to use a hook to customize the indentation of C code. (People often have strong personal preferences for one format compared to another.) Here the hook function is an anonymous lambda expression.

     (setq my-c-style
       '((c-comment-only-line-offset . 4)
         (c-cleanup-list . (scope-operator
                            empty-defun-braces
                            defun-close-semi))
         (c-offsets-alist . ((arglist-close . c-lineup-arglist)
                             (substatement-open . 0)))))
     
     (add-hook 'c-mode-common-hook
       '(lambda ()
          (c-add-style "my-style" my-c-style t)))

It is best to design your hook functions so that the order in which they are executed does not matter. Any dependence on the order is “asking for trouble.” However, the order is predictable: the most recently added hook functions are executed first.

If you play with adding various different versions of a hook function by calling add-hook over and over, remember that all the versions you added will remain in the hook variable together. You can clear out individual functions by calling remove-hook, or do (setq hook-variable nil) to remove everything.

blog comments powered by Disqus