Różnica między init a config w pakiecie use

16

Mam taką konfigurację:

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

Teraz, gdy idę do pliku HTML, widzę, że auto-fillnie jest on wyłączony. Ale jeśli użyję :initzamiast :config, auto-fillzostanie wyłączony. Więc moje pytanie brzmi, kiedy polecenia są :configwykonywane poniżej ?

Sibi
źródło

Odpowiedzi:

16

Różnią się, jeśli pakiet jest odroczony, tzn. Nie jest ładowany, dopóki nie będzie potrzebny. W takim przypadku :initzostanie wykonany w momencie pierwszego odczytu pliku emacs, ale :configzostanie wykonany w momencie załadowania pakietu.

W twoim przykładzie użycie modeniejawnie odkłada ładowanie pakietu. Skonfigurowałeś pakiet do ładowania przy pierwszej wizycie na pliku HTML.

Możesz użyć, :demandaby upewnić się, że pakiet jest zawsze ładowany przy starcie, ale bardziej prawdopodobne jest, że chcesz to zrobić :init.

Z dokumentacji:

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

Ponieważ umieszczasz to w pliku inicjującym użytkownika, oznacza to w zasadzie, że uruchomi się przy starcie.

:config Runs if and when package loads.

Nie uruchamiaj, dopóki pakiet nie zostanie załadowany.

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

Zwróć uwagę na listę rzeczy, które automatycznie powodują odroczenie pakietu. Zasadniczo, jeśli podasz use-packagewarunki, w których potrzebujesz tego pakietu, oznacza to, że nie chcesz go ładować, dopóki te warunki nie wystąpią.

:demand Prevent deferred loading in all cases.

Upewnij się, że pakiet jest ładowany podczas uruchamiania, niezależnie od innych opcji, które określiłeś.

Aktualizacja

Powtórzenie tego w oparciu o ostatnie komentarze ... To, co powiedziałem powyżej, jest prawdą, ale nie sądzę, że poprawnie odpowiada na pytanie. Głównym problemem tutaj jest to, że html-modenie jest to pakiet, ale tryb zdefiniowany przez pakiet sgml-mode. Działa to zgodnie z oczekiwaniami:

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

W oryginalnym przykładzie :configwyrażenie nigdy nie jest oceniane, ponieważ pakiet o nazwie html-modenigdy nie jest ładowany. Przeniesienie tego samego wyrażenia do :initdziała, ponieważ kod inicjujący jest zawsze analizowany, niezależnie od tego, czy pakiet kiedykolwiek zostanie załadowany.

glucas
źródło
@npostavs Dzięki, warto zauważyć. Sam jeszcze nie przeszedłem na use-package 2.0. Po pierwsze, używam :idledość szeroko i nie analizowałem wpływu „: bezczynność została usunięta”.
glucas
1
Nadal nie rozumiem, dlaczego, kiedy odwiedza plik HTML i uruchamia ładowanie pakietu, auto-fillnie jest wyłączony, tzn. Kod konfiguracji nie został uruchomiony. Mam ten sam problem.
Ken Williams
@KenWilliams Twój problem dotyczy również trybu HTML? Myślę, że faktycznym problemem jest to, że html-modenie jest to pakiet. Przynajmniej w mojej obecnej wersji Emacsa html-modejest zdefiniowany w pakiecie sgml-mode. Jeśli więc powiesz use-packagecoś zrobić, gdy html-modezaładowany zostanie pakiet o nazwie , kod nigdy nie zostanie uruchomiony, ponieważ żaden taki pakiet nigdy nie jest ładowany. Musisz umieścić konfigurację trybu HTML w pliku (use-package sgml-mode ....).
glucas
Przepraszam - mój problem dotyczy org-mode, nie html-mode. Podobnym problemem jest to, że pakiet jest wywoływany org-mode, ale pakiet ELPA jest wywoływany org. Może to jest mylące (lub ja)?
Ken Williams
7

Ten przykład bardzo ułatwił mi zrozumienie różnicy między :initi :config. Weźmy przykład ace-windowpakietu (ale może to być dowolny pakiet). Umieść to w swoim init.elpliku:

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

Teraz otwórz emacsa i sprawdź w *Messages*buforze, czy jest tam jakaś hello worldwiadomość. Nie będzie można go znaleźć, ponieważ pakiet jest odroczony. Teraz zmień z configna init:

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

Teraz zamknij i ponownie otwórz emacsa i sprawdź *Messages*bufor. Zobaczysz komunikat, ace window: hello worldponieważ kod jest uruchamiany bez względu na to, kiedy :initzostanie podany. W takim przypadku configbędzie uruchamiany tylko po załadowaniu tego pakietu.

Sibi
źródło
to pomaga, na marginesie, jaka jest różnica między słowem kluczowym :inita :prefacetwoim przykładem?
doktorat
@doctorate: :prefacejest uruchamiany, nawet jeśli dany pakiet jest wyłączony, natomiast :initjest uruchamiany tylko wtedy, gdy pakiet jest włączony.
bbenne10,