Aaron Barclay
Aaron Barclay

Reputation: 945

How to add a hook to only run in a particular mode?

I have the following defun

(defun a-test-save-hook()
  "Test of save hook"
  (message "banana")
  )

that I use via the following hook

(add-hook 'after-save-hook 'a-test-save-hook)

This works as expected. What I would like to do is to limit the hook to particular mode, in this case org-mode. Any ideas as to how I would go about this?

Thanks in advance.

Upvotes: 34

Views: 13254

Answers (2)

Trey Jackson
Trey Jackson

Reputation: 74430

If you take a look at the documentation for add-hook (or C-h f add-hook RET), you'll see that one possible solution is to make the hook local to the major modes you want. This is slightly more involved than vderyagin's answer, and looks like this:

(add-hook 'org-mode-hook 
          (lambda () 
             (add-hook 'after-save-hook 'a-test-save-hook nil 'make-it-local)))

The 'make-it-local is the flag (can be anything that isn't nil) that tells add-hook to add the hook only in the current buffer. With the above, you'll only get the a-test-save-hook added in org-mode.

This is nice if you want to use a-test-save-hook in more than one mode.

The documentation for add-hook is:

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 default value.
This makes the hook buffer-local if needed, and it makes t a member
of the buffer-local value.  That acts as a flag to run the hook
functions in the default 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.

Upvotes: 62

Victor Deryagin
Victor Deryagin

Reputation: 12215

Simplest solution, i suppose, is to add major-mode checking in the hook itself:

(defun a-test-save-hook()
  "Test of save hook"
  (when (eq major-mode 'org-mode)
    (message "banana")))

(add-hook 'after-save-hook 'a-test-save-hook)

Upvotes: 8

Related Questions