Різниця між init та config у use-package


16

У мене така конфігурація:

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

Тепер, коли я заходжу в HTML-файл, я помічаю, що auto-fillвін не вимкнено. Але якщо я використовую :initзамість :config, auto-fillвимикається. Отже, моє запитання - коли виконуються команди :config?

Відповіді:


16

Вони різні, якщо пакет відкладений, тобто не завантажений, поки це не потрібно. У цьому випадку :initвін буде виконаний під час першого читання файлу emacs, але :configвін буде виконуватися під час фактичного завантаження пакета.

У вашому прикладі використання modeнеявно відкладає завантаження пакету. Ви налаштували пакет для завантаження при першому відвідуванні HTML-файлу.

Ви можете використати :demandдля того, щоб переконатися, що пакет завжди завантажений під час запуску, але більш імовірно, що ви хочете тут зробити, це надіти свій гачок :init.

З докстрингу:

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

Оскільки ви поміщаєте це у свій файл-init, це в основному означає, що воно запуститься при запуску.

:config Runs if and when package loads.

Отже, не запускайте, поки пакет фактично не завантажується ..

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

Зауважте список речей, які автоматично відкладають пакет. В основному, якщо ви повідомляєте use-packageумови, в яких вам потрібен цей пакет, він передбачає, що ви не хочете завантажувати його, поки ці умови не виникнуть.

:demand Prevent deferred loading in all cases.

Переконайтеся, що пакет завантажений під час запуску, незалежно від того, які інші опції ви вказали.

Оновлення

Переглянувши це, грунтуючись на останніх коментарях ... Те, що я сказав вище, все правда, але я не думаю, що це правильно відповідає на питання. Основна проблема тут насправді в тому, що html-modeце не пакет, а скоріше режим, визначений пакетом sgml-mode. Це працює так, як очікувалося для мене:

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

У оригінальному прикладі :configвираз ніколи не оцінюється, оскільки пакет з назвою html-modeніколи не завантажується. Переміщення того ж виразу на :initроботу, тому що код init завжди оцінюється, незалежно від того, чи завантажується пакет.



@npostavs Спасибі, варто відзначити. Я ще не перейшов на використання пакета 2.0 сам. По-перше, я використовую :idleдосить широко і не розглядаю вплив ": простою було вилучено".
глюкас

1
Я досі не розумію, чому він, коли він відвідує HTML-файл і запускає пакет для завантаження, auto-fillне вимикається, тобто конфігураційний код не запускався. У мене така ж проблема.
Кен Вільямс

@KenWilliams Ваша проблема також із html-режимом? Я думаю, що актуальною проблемою є те, що html-modeце не пакет. Принаймні в моїй поточній версії Emacs, html-modeвизначеної в пакеті sgml-mode. Тож якщо ви скажете use-packageзробити щось, коли html-modeзавантажений ім'я пакета , той код ніколи не запускається, оскільки такий пакет ніколи не завантажується. Потрібно поставити налаштування режиму html в (use-package sgml-mode ....).
глюкас

Вибачте - моя проблема з org-mode, не html-mode. Аналогічна проблема полягає в тому, що пакет викликається org-mode, але викликається пакет ELPA org. Може, це бентежить (чи мене)?
Кен Вільямс

7

Цей приклад мені дуже легко зрозумів різницю між :initта :config. Візьмемо приклад ace-windowпакету (але це може бути будь-який пакет). Помістіть це у свій init.elфайл:

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

Тепер відкрийте свої emacs і побачите в *Messages*буфері, щоб побачити, чи є hello worldповідомлення. Ви не зможете знайти жодного, оскільки пакет відкладений. Тепер перехід від configдо init:

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

Тепер закрийте та знову відкрийте emacs та огляньте *Messages*буфер. Ви побачите повідомлення, ace window: hello worldоскільки код запускається незалежно від того, коли він :initбуде наданий. У разі configйого запуску буде лише тоді, коли пакет завантажений.


це допомагає, лише побічне запитання, у чому різниця між ключовим словом :initта :prefaceна основі вашого прикладу?
докторантура

@doctors: :prefaceзапускається, навіть якщо відповідний пакет вимкнено, тоді як :initвін запускається лише тоді, коли пакет увімкнено.
bbenne10
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.