35

I have foo-mode and would enable bar-minor-mode for it. So which way is more common and preferable?

A

(add-hook 'foo-mode-hook 'bar-minor-mode)

B

(add-hook 'foo-mode-hook (lambda ()
                           "Turn on `bar-minor-mode' mode."
                           (bar-minor-mode 1)))

C

(defun bar-minor-mode-on ()
  "Turn on `bar-minor-mode' mode."
  (interactive)
  (bar-minor-mode 1))

(add-hook 'foo-mode-hook 'bar-minor-mode-on)

D

• variant C, but function pushed to upstream

E

• variant C, but function stored in plugin's recipe

2

3 Answers 3

33

It depends on which version(s) of Emacs you are using (or targeting). Iff you are exclusively using Emacs 24+ then you can safely use variant A:

* Incompatible Lisp Changes in Emacs 24.1

** Passing a nil argument to a minor mode function call now ENABLES
the minor mode unconditionally.  This is so that you can write e.g.

 (add-hook 'text-mode-hook 'foo-mode)

to enable foo-mode in Text mode buffers, removing the need for
`turn-on-foo-mode' style functions.  This affects all mode commands
defined by `define-minor-mode'.  If called interactively, the mode
command still toggles the minor mode.

That's from the NEWS file, but as per the comments it's good practice to use function-quoting for function symbols, like so:

 (add-hook 'text-mode-hook #'foo-mode)

If the code might need to run under Emacs 23 (or earlier), then I would go with variant C, as personally I dislike seeing anonymous functions in hook variables. (I'm not sure I understand what you mean by variants D & E, mind).

3
9

Why would you define a new command that does exactly what bar-minor-mode does?

Starting with 24.1, all of these are completely equivalent, so just use the less redundant one: option A

(add-hook 'foo-mode-hook #'bar-minor-mode)
4
  • 1
    Is it safe solution? I mean if one of foo-mode-hook parent modes have same hook than bar-minor-mode will call twice, so will be disabled. Unexpected behavior.
    – Netsu
    Dec 14, 2014 at 3:37
  • 2
    @Netsu yes, calling a minor mode function with no arguments ENABLES the minor mode unconditionally.
    – Malabarba
    Dec 14, 2014 at 7:57
  • 4
    @Malabarba Only as of Emacs 24. In earlier versions it's l it'd actually toggle the mode.
    – user227
    Dec 14, 2014 at 10:41
  • 1
    @lunaryorn Yes, that's why phils' answer is better. :-) I was being too lazy to fix mine.
    – Malabarba
    Dec 14, 2014 at 19:50
8

Here's one more way to do it that has some advantages, assuming that you're editing your own config, not a package that you distribute.

(add-hook 'foo-mode-hook
          #'custom-foo-hook)

(defun custom-foo-hook ()
  (bar-minor-mode 1)
  (baz-minor-mode 1)
  ;; ...
  (define-key foo-mode-map "C-c C-b" #'foobar))

The advantage is that everything is stored in one hook, so to disable some stuff, you don't have to do remove-hook, but instead comment some stuff in custom-foo-hook and C-M-x.

You can even write a command that jumps from any mode to it's custom hook.

3
  • 1
    This is (essentially) variant C with a different name, but I agree it's worth emphasising. This is certainly the approach I take when I'm customising major mode behaviours in my own config.
    – phils
    Dec 14, 2014 at 20:49
  • 1
    Variant C implies multiple add-hook statements for each minor mode to enable. I wanted to emphasize that having only one add-hook statement is an advantage.
    – abo-abo
    Dec 14, 2014 at 21:20
  • Agreed. In my head I pretty much translated variant C to "define a custom function which enables the mode" rather than "define a custom function which only enables the mode", but in retrospect the latter does seem to have been the intent. As you say, it depends upon whether or not the code is for personal use.
    – phils
    Dec 14, 2014 at 21:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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