Differenza tra init e config in use-package


16

Ho una configurazione come questa:

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

Ora, quando vado a visitare un file HTML, osservo che auto-fillnon è disattivato. Ma se uso :initinvece di :config, auto-fillviene disattivato. Quindi la mia domanda è: quando vengono :configeseguiti i comandi ?

Risposte:


16

Sono diversi se il pacchetto viene rinviato, ovvero non caricato fino a quando non è necessario. In tal caso :initverrà eseguito al momento della prima lettura del file emacs, ma :configverrà eseguito al momento del caricamento effettivo del pacchetto.

Nel tuo esempio, l'uso di modedifensori impliciti durante il caricamento del pacchetto. Hai configurato il pacchetto per il caricamento la prima volta che viene visitato un file html.

È possibile utilizzare :demandper assicurarsi che il pacchetto sia sempre caricato all'avvio, ma molto probabilmente quello che si desidera fare qui è agganciare :init.

Dalla dotstring:

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

Dal momento che lo stai inserendo nel tuo file init utente, ciò significa sostanzialmente che verrà eseguito all'avvio.

:config Runs if and when package loads.

Quindi, non eseguire fino a quando il pacchetto non viene effettivamente caricato.

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

Nota l'elenco delle cose che fanno differire automaticamente un pacchetto. Fondamentalmente se si dicono use-packagele condizioni in cui è necessario questo pacchetto, si presume che non si desideri caricarlo fino a quando non si verificano tali condizioni.

:demand Prevent deferred loading in all cases.

Assicurati che il pacchetto sia caricato all'avvio, indipendentemente da quali altre opzioni hai specificato.

Aggiornare

Rivisitare questo in base ai commenti recenti ... Quello che ho detto sopra è tutto vero, ma non credo che risponda correttamente alla domanda. Il problema alla radice qui è in realtà che html-modenon è un pacchetto, ma piuttosto una modalità definita dal pacchetto sgml-mode. Questo funziona come previsto per me:

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

Nell'esempio originale, l' :configespressione non viene mai valutata perché un pacchetto denominato html-modenon viene mai caricato. Spostare la stessa espressione su :initfunziona perché il codice di inizializzazione viene sempre valutato, indipendentemente dal fatto che il pacchetto venga mai caricato.



@npostavs Grazie, vale la pena notare. Non sono ancora passato a use-package 2.0 da solo. Per prima cosa, uso :idleampiamente e non ho esaminato l'impatto di ": il minimo è stato rimosso".
glucas,

1
Continuo a non capire perché, quando visita un file HTML e avvia il caricamento del pacchetto, auto-fillnon viene disattivato, ovvero il codice di configurazione non è stato eseguito. Ho lo stesso problema.
Ken Williams,

@KenWilliams Il tuo problema riguarda anche la modalità HTML? Penso che il vero problema qui sia che html-modenon è un pacchetto. Almeno nella mia attuale versione di Emacs, html-modeè definito nel pacchetto sgml-mode. Quindi, se dici use-packagedi fare qualcosa quando html-modeviene caricato un pacchetto chiamato, quel codice non viene mai eseguito perché non viene mai caricato alcun pacchetto del genere. Devi inserire la configurazione in modalità html in a (use-package sgml-mode ....).
glucas,

Siamo spiacenti, il mio problema è con org-mode, no html-mode. Un problema simile è che viene chiamato il pacchetto org-mode, ma viene chiamato il pacchetto ELPA org. Forse questo lo confonde (o io)?
Ken Williams,

7

Questo esempio mi ha reso molto facile comprendere la differenza tra :inite :config. Facciamo un esempio di ace-windowpacchetto (ma questo può essere qualsiasi pacchetto). Metti questo nel tuo init.elfile:

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

Ora apri i tuoi emacs e vedi nel *Messages*buffer per vedere se c'è qualche hello worldmessaggio. Non sarai in grado di trovarne nessuno perché il pacchetto è rinviato. Ora cambia da configa init:

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

Ora chiudi e riapri emacs e ispeziona il *Messages*buffer. Vedrai il messaggio ace window: hello worldperché il codice viene eseguito indipendentemente da quando :initviene fornito. In questo caso configverrà eseguito solo quando quel pacchetto viene caricato.


che aiuta, solo una domanda secondaria, qual è la differenza tra la parola chiave :inite in :prefacebase al tuo esempio?
dottorato

@doctorate: :prefaceviene eseguito anche se il pacchetto in questione è disabilitato mentre :initviene eseguito solo quando un pacchetto è abilitato.
bbenne10
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.