Différence entre init et config dans use-package

16

J'ai une configuration comme celle-ci:

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

Maintenant, quand je vais visiter un fichier HTML, je constate qu'il auto-filln'est pas désactivé. Mais si j'utilise à la :initplace de :config, auto-fills'éteint. Donc ma question est quand les commandes sont-elles sous- :configexécutées?

Sibi
la source

Réponses:

16

Ils sont différents si le package est différé, c'est-à-dire qu'il n'est pas chargé jusqu'à ce qu'il soit nécessaire. Dans ce cas, :initil sera exécuté au moment de la première lecture de votre fichier emacs, mais :configsera exécuté au moment où le paquet est réellement chargé.

Dans votre exemple, l'utilisation de modediffère implicitement le chargement du package. Vous avez configuré le package pour qu'il soit chargé la première fois qu'un fichier html est visité.

Vous pouvez utiliser :demandpour vous assurer que le package est toujours chargé au démarrage, mais plus probablement ce que vous voulez faire ici est de mettre votre crochet :init.

De la docstring:

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

Puisque vous placez cela dans votre fichier d'initialisation utilisateur, cela signifie essentiellement qu'il s'exécutera au démarrage.

:config Runs if and when package loads.

Donc, ne courez pas tant que le paquet n'est pas réellement chargé.

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

Notez la liste des choses qui rendent automatiquement un package différé. Fondamentalement, si vous indiquez use-packageles conditions dans lesquelles vous avez besoin de ce package, cela suppose que vous ne voulez pas le charger jusqu'à ce que ces conditions se produisent.

:demand Prevent deferred loading in all cases.

Assurez-vous que le package est chargé au démarrage, quelles que soient les autres options que vous avez spécifiées.

Mise à jour

Revisiter cela sur la base des commentaires récents ... Ce que j'ai dit ci-dessus est tout à fait vrai, mais je ne pense pas qu'il réponde correctement à la question. Le problème racine ici est en fait qu'il html-modene s'agit pas d'un package, mais plutôt d'un mode défini par le package sgml-mode. Cela fonctionne comme prévu pour moi:

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

Dans l'exemple d'origine, l' :configexpression n'est jamais évaluée car un package nommé html-moden'est jamais chargé. Le déplacement de la même expression :initfonctionne car le code init est toujours évalué, que le package soit ou non chargé.

glucas
la source
@npostavs Merci, à noter. Je ne suis pas encore passé à use-package 2.0 moi-même. D'une part, j'utilise :idleassez largement et je n'ai pas examiné l'impact de ": l'inactivité a été supprimée".
glucas
1
Je ne comprends toujours pas pourquoi, lorsqu'il visite un fichier HTML et déclenche le chargement du paquet, il auto-filln'est pas désactivé, c'est-à-dire que le code de configuration ne s'est pas exécuté. J'ai le même problème.
Ken Williams du
@KenWilliams Votre problème concerne également le mode html? Je pense que le vrai problème ici est que ce html-moden'est pas un paquet. Au moins dans ma version actuelle d'Emacs, html-modeest défini dans le package sgml-mode. Donc, si vous dites use-packagede faire quelque chose lorsqu'un package nommé html-modeest chargé, ce code ne s'exécute jamais car aucun package de ce type n'est jamais chargé. Vous devez mettre la configuration en mode html dans un fichier (use-package sgml-mode ....).
glucas
Désolé - mon problème est avec org-mode, non html-mode. Un problème similaire est que le package est appelé org-mode, mais le package ELPA est appelé org. C'est peut-être déroutant (ou moi)?
Ken Williams
7

Cet exemple m'a permis de comprendre la différence entre :initet :config. Prenons un exemple de ace-windowpackage (mais cela peut être n'importe quel package). Mettez ceci dans votre init.eldossier:

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

Ouvrez maintenant votre emacs et voyez dans le *Messages*tampon pour voir s'il y a un hello worldmessage. Vous ne pourrez pas en trouver car le package est différé. Passez maintenant de configà init:

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

Maintenant, fermez et rouvrez emacs et inspectez le *Messages*tampon. Vous verrez le message ace window: hello worldcar le code est exécuté quel que soit le moment où il :initest donné. Dans ce cas, configil ne sera exécuté que lorsque ce package sera chargé.

Sibi
la source
cela aide, juste une question secondaire, quelle est alors la différence entre le mot clé :initet :prefacebasé sur votre exemple?
doctorat le
@doctorate: :prefaceest exécuté même si le package en question est désactivé alors qu'il :initn'est exécuté que lorsqu'un package est activé.
bbenne10