I'd like to register an after-save-hook that is only active in certain buffers that I specify.

For example, assume there are 3 functions currently registered in my after-save-hook: hook-01, hook-02, and hook-03. In all cases after save-buffer is called, I'd like hook-01, hook-02, and hook-03 to be invoked, and I realize that this is the normal after-save-hook behavior.

However, in certain buffers and only those buffers, I want an additional hook, special-hook, to also be called after save-buffer is invoked, so that in these special buffers, all 4 hooks are run after the buffer is saved.

Is there a way to register a hook function that is added to after-save-hook only within certain specified buffers?

I control when those special buffers are entered, so I can cause special elisp code to run upon entry into those buffers. I just don't know how to specify a hook that is only valid in a given buffer.

  • 1
    Probably a better way is to just check in special-hook if you are in one of your special buffers. That way, other code can still add hooks to after-save-hook. – Qudit Apr 14 '18 at 19:44
  • 1
    Possible duplicate of Run command after each type/insert – Drew Apr 15 '18 at 15:21

This is standard functionality built into add-hook:

add-hook is a compiled Lisp function in ‘subr.el’.

(add-hook HOOK FUNCTION &optional APPEND LOCAL)

Add to the value of HOOK the function FUNCTION. FUNCTION is not added if already present. FUNCTION is added (if necessary) at the beginning of the hook list unless the optional argument APPEND is non-nil, in which case FUNCTION is added at the end.

The optional fourth argument, LOCAL, if non-nil, says to modify the hook’s buffer-local value rather than its global value. This makes the hook buffer-local, and it makes t a member of the buffer-local value. That acts as a flag to run the hook functions of the global value as well as in the local value.

HOOK should be a symbol, and FUNCTION may be any valid function. If HOOK is void, it is first set to nil. If HOOK’s value is a single function, it is changed to a list of functions.

| improve this answer | |

Actually, this is easier than I thought. Upon entering the special buffer, all I have to do is this ...

(make-variable-buffer-local 'after-save-hook)
(add-hook 'after-save-hook 'special-hook)

I had tried that before and thought it didn't work, but now I realize that I was testing it incorrectly.

| improve this answer | |
  • 1
    You can also use (add-hook 'after-save-hook 'special-hook nil t), the last argument means to add to the buffer local value. – npostavs Apr 14 '18 at 20:38
  • 1
    @HippoMan make-variable-buffer-local makes the specified var buffer-local "whenever it is set". It is used in tandem with a variable definition (although nowadays you typically would use defvar-local). To make an existing var have a buffer-local value in the current buffer, you would in general use make-local-variable (or nowadays setq-local) -- but for hooks you don't want that either, because as npostavs points out add-hook has direct support for what you want to do. – phils Apr 15 '18 at 6:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.