25

I have a configuration like this:

(use-package html-mode
  :mode "\\.html\\'"
  :config
  (progn
    (add-hook 'html-mode-hook 'turn-off-auto-fill)))

Now when I go and visit an HTML file, I observe that auto-fill is not turned off. But if I use :init instead of :config, auto-fill gets turned off. So my question is when are the commands under :config executed ?

2 Answers 2

29

They are different if the package is deferred, i.e. not loaded until it is needed. In that case :init will be executed at the time your emacs file is first read, but :config will be executed at the time the package is actually loaded.

In your example, the use of mode implicitly defers loading the package. You have configured the package to be loaded the first time an html file is visited.

You could use :demand to make sure the package is always loaded at startup, but more likely what you want to do here is put your hook in :init.

From the docstring:

:init Code to run when `use-package' form evals.

Since you're putting this in your user-init file, that basically means it will run at startup.

:config Runs if and when package loads.

So, not run until the package is actually being loaded..

:defer Defer loading of package -- automatic if :commands, :bind, :bind*,  :mode or :interpreter are used.

Note the list of things that automatically make a package deferred. Basically if you tell use-package the conditions in which you need this package, it assumes you don't want to load it until those conditions arise.

:demand Prevent deferred loading in all cases.

Make sure the package is loaded at startup, regardless of what other options you've specified.

Update

Revisiting this based on the recent comments... What I said above is all true, but I don't think it correctly answers the question. The root problem here is actually that html-mode is not a package, but rather a mode defined by the package sgml-mode. This works as expected for me:

(use-package sgml-mode
  :mode ("\\.html\\'" . html-mode)
  :config (add-hook 'html-mode-hook 'turn-off-auto-fill))

In the original example, the :config expression never gets evaluated because a package named html-mode never gets loaded. Moving the same expression to :init works because init code is always evaluated, regardless of whether the package ever gets loaded.

7
  • 1
    See Semantics of :init is now consistent
    – npostavs
    Mar 30, 2015 at 18:04
  • @npostavs Thanks, worth noting. I haven't yet moved to use-package 2.0 myself. For one thing, I use :idle pretty extensively and haven't looked into the impact of ":idle has been removed".
    – glucas
    Mar 30, 2015 at 19:24
  • 1
    I still don't understand why, when he visits an HTML file and triggers the package to load, auto-fill is not turned off, i.e. the config code didn't run. I have the same problem. Oct 28, 2015 at 15:10
  • @KenWilliams Your issue is with html-mode as well? I think the actual problem here is that html-mode is not a package. At least in my current version of Emacs, html-mode is defined in the package sgml-mode. So if you tell use-package to do something when a package named html-mode is loaded that code never runs because no such package is ever loaded. You need to put html-mode setup in a (use-package sgml-mode ....).
    – glucas
    Oct 28, 2015 at 15:33
  • Sorry - my issue is with org-mode, not html-mode. A similar issue there is that the package is called org-mode, but the ELPA package is called org. Maybe that's confusing it (or me)? Oct 28, 2015 at 16:16
11

This example made me much easy to understand the difference between :init and :config. Let's take an example of ace-window package (but this can be any package). Put this in your init.el file:

(use-package ace-window
  :ensure t
  :defer t
  :config
  (progn
    (message "ace window: hello world")))

Now open your emacs and see in the *Messages* buffer to see if there any hello world message. You won't be able to find any because the package is deferred. Now change from config to init:

(use-package ace-window
  :ensure t
  :defer t
  :init
  (progn
    (message "ace window: hello world")))

Now close and re-open emacs and inspect the *Messages* buffer. You will see the message ace window: hello world because the code is run no matter what when :init is given. In the case of config it will be only run when that package is loaded.

2
  • 1
    that helps, just a side question, what is the difference then between the keyword :init and :preface based on your example?
    – doctorate
    Jul 14, 2017 at 11:19
  • 2
    @doctorate: :preface is run even if the package in question is disabled whereas :init is only run when a package is enabled.
    – bbenne10
    Jul 2, 2018 at 12:31

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.