use-package
use-package copied to clipboard
`:after` does not respect `after-load-alist` insertion order
Forgive me if this was intended, but this is something that bites me often, when I use use-package in Doom Emacs. I'll illustrate the issue with these two snippets:
(with-eval-after-load 'foo
(message "1"))
(use-package foo
:defer t
:config (message "2"))
(with-eval-after-load 'foo
(message "3"))
(require 'foo) ; #=> prints 1, 2, then 3
(with-eval-after-load 'foo
(message "1"))
(use-package foo
:after bar
:config (message "2"))
(with-eval-after-load 'foo
(message "3"))
(require 'bar) ; #=> 1, 3, then 2
This is because the use-package block for foo expands to:
(eval-after-load 'bar
'(progn
(require 'foo nil nil) ; executes all of `foo's after-load-alist handlers
(message "2")
t))
But should it not respect insertion order into after-load-alist? e.g.
(eval-after-load 'foo
'(message "2"))
(eval-after-load 'bar
'(progn
(require 'foo nil nil)
t))
EDIT: Corrected a couple mistakes in the examples.
I can confirm I experience the same behavior. While :after does enforce a loading order, the initialization (:init and :config) is essentially inverted in a stack-like fashion:
- load
bar - load
foo - init
foo - init
bar
In my opinion the expected order would be:
- load
bar - init
bar - load
foo - init
foo
The way I understand it, it makes :after useful only as a fancy :defer as the actual initialization order is too confusing for the intended use. The example in the readme does not seem to be practical either as ivy-hydra should require hydra and ivy on its own so :defer t for ivy and hydra should be enough and no external ordering should be needed (possibly with an :ensure caveat but the general use case does seem wrong).