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

Stefan
  • 26,154
  • 3
  • 46
  • 84
Netsu
  • 555
  • 1
  • 5
  • 9
  • 4
    Hi @Netsu, I noticed you added back the quote I had removed from your lambda. In general, it's harmful to quote lambdas, so Stefan and I are just trying to motivate good practices. :-) – Malabarba Dec 14 '14 at 19:48
  • 2
    [Enabling/disabling/toggling a minor mode interactively or using elisp](http://emacs.stackexchange.com/a/10971/115) – Kaushal Modi May 07 '15 at 18:49

3 Answers3

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).

phils
  • 48,657
  • 3
  • 76
  • 115
  • 4
    You should preferably use function quotes for the minor mode, so that the byte compiler can warn you if the mode is undefined. –  Dec 14 '14 at 10:43
  • Thanks. But is function-quoting still necessary? What advantages it gives? Also is it necessary for lambdas as well? – Netsu Dec 15 '14 at 15:51
  • 2
    See any/all of http://stackoverflow.com/questions/16801396/when-should-emacs-function-syntax-be-used http://stackoverflow.com/questions/1852844/emacs-lisp-difference-between-function-lambda-and-lambda http://stackoverflow.com/questions/25275842/does-function-serve-any-purpose-in-emacs http://stackoverflow.com/questions/20948325/why-not-quoting-lambda http://emacs.stackexchange.com/questions/3595/when-to-sharp-quote-a-lambda-expression – phils Dec 15 '14 at 21:04
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)
Malabarba
  • 22,878
  • 6
  • 78
  • 163
  • 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 '14 at 03:37
  • 2
    @Netsu yes, calling a minor mode function with no arguments ENABLES the minor mode unconditionally. – Malabarba Dec 14 '14 at 07:57
  • 4
    @Malabarba Only as of Emacs 24. In earlier versions it's l it'd actually toggle the mode. –  Dec 14 '14 at 10:41
  • 1
    @lunaryorn Yes, that's why phils' answer is better. :-) I was being too lazy to fix mine. – Malabarba Dec 14 '14 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.

abo-abo
  • 13,943
  • 1
  • 29
  • 43
  • 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 '14 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 '14 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 '14 at 21:28