[The OP has already answered his question in a comment above, but I dug a little to understand what was going on.]
As the OP points out in a comment:
(use-package org
:hook (org-mode . foo))
works fine.
You can use macroexpand
to see what the macro expands to:
(pp (macroexpand '(use-package org :hook (org-mode . foo)))) ===>
(progn
(defvar use-package--warning8
#'(lambda (keyword err)
(let
((msg
(format "%s/%s: %s" 'org keyword
(error-message-string err))))
(display-warning 'use-package msg :error))))
(condition-case-unless-debug err
(progn
(unless (fboundp 'foo) (autoload #'foo "org" nil t))
(add-hook 'org-mode-hook #'foo))
(error (funcall use-package--warning8 :catch err))))
As you can see, the function foo
is added to org-mode-hook
and everything is fine. But if you try the original form the OP used:
(pp (macroexpand '(use-package org :hook (org-mode . #'foo))))
(progn
(defvar use-package--warning9
#'(lambda (keyword err)
(let
((msg
(format "%s/%s: %s" 'org keyword
(error-message-string err))))
(display-warning 'use-package msg :error))))
(condition-case-unless-debug err
(progn
(unless (fboundp 'org-mode) (autoload #'org-mode "org" nil t))
(add-hook 'org-mode-hook #'org-mode)
(add-hook 'function-hook #'org-mode)
(add-hook 'foo-hook #'org-mode))
(error (funcall use-package--warning9 :catch err))))
you can see three hooks are modified and they are modified incorrectly.
Part of the explanation is that #'foo
is shorthand for (function foo)
and if you try to macroexpand (use-package org :hook (org-mode . (function foo)))
you get the same expansion as for #'foo
.
The problem is that the expression (a . (b c))
is equal to the list (a b c)
, so when use-package
sees (org-mode . (function foo))
, it sees the same thing as if you had said (org-mode function foo)
and interprets that as needing to set multiple hooks - see the second paragraph of section Hooks. Notice that there is no such thing as function-hook
or foo-hook
, but add-hook
creates the variables if they don't exist already (do C-h f add-hook
and read the doc string). They don't do any harm here because nobody uses them. But setting org-mode-hook
to org-mode
is indeed fatal.
The remaining question is: why are the three hooks (one real, two manufactured by use-package
) set to #'org-mode
, rather than to nil
say? I don't know the answer to that; I would have to go through the guts of the macro and given that I don't use use-package
, I will leave it at that.
As I suggested in a comment, it is worth opening an issue on the use-package
Github site. You might also let the people who provided the online examples that you copied, know that they should fix their code.
EDIT: In a comment to this answer it is stated that "...if you pass only one argument (or a list of symbols) [as the value of the :hook
keyword], use-package
assumes those are the modes you want to activate your current 'use-package package'...". Although the description is not quite clear, I take it to mean that if you don't specify a function to add to the list of hooks (as in this case), it will take the name of the package you are setting up (org
in this case), tack a -mode
afterwards (org-mode
in this case) and use that as the function. If that is indeed the case (and after some rudimentary checking, it seems that that is indeed the case), that would explain the above results, but it seems a somewhat bizarre interpretation by use-package
of what the user wants to do.
It is also stated in that comment that the use-package Github page documents the above behavior, but I failed to find any reference to it. Caveat emptor.