use-package
use-package copied to clipboard
:after macro does not seem to work
So I was noticing a problem every now and again while working on my emacs config where the custom faces I was setting were being reset somehow. I now know that this is a conflict with my theme package overriding the variables I was setting because it was being loaded after some of the set faces. I realised that by loading the theme first this wasn't an issue. So wanting to make it syntactically sugary I used :after. Nothing happened. Sometimes I could get it to work with :require from req package, however if I used it with any more than 1 package one of the packages it got overridden. I tried moving the whole of the of color-theme-sanityinc-tomorrow's req-package/use-package wrapper to the top. and it works! I also tried loading the theme near the beginning of the config, and putting the custom set faces near the bottom. Both worked, so I can only assume it's a problem with :after macro. Unless I'm misunderstanding how :after and load order works. with use-package.
I have kinda the same problem, with the following config:
(use-package use-package
:custom
(use-package-verbose t)
(use-package-always-ensure t)
(use-package-always-defer t))
(use-package dired-filter
:demand t
:after dired)
If I don't use :demand t for dired-filter it does not get loaded when I enter dired buffers, yet my understanding was that :after should have taken care of that.
Yes, :after should indeed have taken care of that. I'd recommend expanding the macros, and inserting some messaging to track down why it's not demand loading when you believe it should be?
Without :demand t the macro expands to:
(progn
(use-package-ensure-elpa 'dired-filter
'(t)
'nil)
(defvar use-package--warning219
(function
(lambda
(keyword err)
(let
((msg
(format "%s/%s: %s" 'dired-filter keyword
(error-message-string err))))
(display-warning 'use-package msg :error)))))
(condition-case-unless-debug err nil
(error
(funcall use-package--warning219 :catch err))))
My guess is that use-package-always-defer is not correctly handled reguarding :after.
On second thought, I think the behavior here is right.
In the default case, with always-defer set to nil, the form you have expands to this:
(eval-after-load 'dired
'(require 'dired-filter nil nil))
If I instead say:
(use-package dired-filter
:defer t
:after dired)
What this means is: After dired has loaded, defer loading of dired-filter. Since you have no conditions that would cause dired-filter to ever be loaded (such as registering a command autoload), use-package determines that there's nothing will ever happen as a result of this declaration.
Compare this with:
(use-package dired-filter
:commands hello
:defer t
:after dired)
yields:
(eval-after-load 'dired
'(unless
(fboundp 'hello)
(autoload
(function hello)
"dired-filter" nil t)))
So on this basis, what you seem to want is that the use of :after is already a kind of deferral, and thus shouldn't interpret the use-package declaration as still deferred once the :after condition is met.
Given current semantics, the right answer is what you've done, by adding :demand t, so that loading of dired-filter isn't still deferred after dired has loaded.
Alright :smirk: thanks!
@jwiegley: not sure you answered @Mallchad 's question tho
@Silex yeah not really a conclusive answer, I've finally got a brief chance to mess around a bit more. I've tried all manors of combinations with defer, demand and after, as well and changing the declaration of the use-package around, as well as trying req-package vs use-package, evaluating buffer vs restarting emacs, I even tried evaluating a small part of section of my config from scratch. In every case, the packages load in the order their use-package is declared in. The only part of :after that appears to work is if the package listed trailing :after cannot be found then the package will not load, but it won't change the order of the loading.
I got caught by this as well.
I saw jwiegley's comments and tried to use after. I think the problem was that the first package was already on a defer e.g.
(use-package yasnippet
:defer 2
:config
(setq yas-snippet-dirs (list "snippets")))
(use-package yasnippet-collection
:after yasnippet
:demand)
Now both have code in a (eval-after-load 'yasnippet ... ) construction. (yasnippet's is the :config block and for yasnippet-collection it's the whole thing) What order do they run in?
My workround was to put the dependant use-package inside the config of the first.
(use-package yasnippet
:defer 2
:config
(setq yas-snippet-dirs (list "snippets"))
(use-package yasnippet-collection))
I can't get :after working with :pretty-hydra
(use-package ace-jump-mode
:after (hydra pretty-hydra)
:pretty-hydra
(ace-jump-hydra
(:color red :quit-key "q")
("move point like a vim."
(("h" backward-char :color red)
("j" next-line :color red)
("k" previous-line :color red)
("l" forward-char :color red))))
)
Currently to work around this, I make sure the hydra and pretty-hydra is loaded first manually like below:
(use-package hydra
...)
(use-package pretty-hydra
...)
(use-package ace-jump-mode
...) ; same the above
My workround was to put the dependant use-package inside the config of the first.
(use-package yasnippet :defer 2 :config (setq yas-snippet-dirs (list "snippets")) (use-package yasnippet-collection))
I think this is what you should do in this case, and we will add this to the documentation as discussed in #710. Does that resolve this issue?
Yeah it does as a work around. It's been a while since I've looked at it and my config has morphed a lot since then-
it seems my preferred way is making monolothic use-package bindings for related packages through req-package.
It's basically the same as nested use-packages just tidier.
The other thing I did was just try to be tidier in general. Better use of binding maps, local bindings and creating advice and hooks so things that need it are reset when they need anyway. It's sometimes more stable for longer sessions. Appending things to binding maps and variables where permitted and stuff.
I tried to do some more testing to gague behaviour.
Had a hard time getting it to trigger any problematic behaviour at all and temproarily switched 2 packages to
use-package only bindings.
color-theme-sanityinc-tomorrow and avy. The issue here in the past was theme loadng override my custom avy faces.
But since have rarely cared.
- If
avy's use-package is abovecolor-theme-sanityinc-tomorrow. It's fine. Avy loads after and overrides the faces. - If
avyis below. It loads after and it's faces are clobbered. - If either have implied defer bindings the order is messed up and it sometimes can clobber
avy's faces. - If
:demand tis used deferring is ignorred entirely and it's loaded instantly - If
:afterand:demandis used onavythen:afteris overriden, it loads early and the face's are clobbered. - This behaviour kind of makes sense.
But there is a gap if you really wanted to say "load immediately but not before :after packages cuz it'll break".
I don't need this fix myself anymore it just seems like quirky and unintuitive behaviour-
not like there is an error of an :after being overriden or anything