Perbedaan antara init dan config dalam paket penggunaan

16

Saya memiliki konfigurasi seperti ini:

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

Sekarang ketika saya pergi dan mengunjungi file HTML, saya perhatikan itu auto-filltidak dimatikan. Tetapi jika saya menggunakan :initsebagai gantinya :config, auto-filldimatikan. Jadi pertanyaan saya adalah kapan perintah di bawah :configdieksekusi?

Sibi
sumber

Jawaban:

16

Mereka berbeda jika paket ditangguhkan, yaitu tidak dimuat sampai diperlukan. Dalam hal ini :initakan dieksekusi pada saat file emacs Anda pertama kali dibaca, tetapi :configakan dieksekusi pada saat paket itu sebenarnya dimuat.

Dalam contoh Anda, penggunaan modesecara implisit mencegah pemuatan paket. Anda telah mengonfigurasi paket untuk dimuat saat pertama kali file html dikunjungi.

Anda bisa menggunakan :demanduntuk memastikan paket selalu dimuat saat startup, tetapi lebih mungkin apa yang ingin Anda lakukan di sini adalah memasukkan kait Anda :init.

Dari docstring:

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

Karena Anda meletakkan ini di file user-init Anda, itu pada dasarnya berarti akan berjalan saat startup.

:config Runs if and when package loads.

Jadi, jangan dijalankan sampai paket benar-benar dimuat ..

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

Perhatikan daftar hal-hal yang secara otomatis membuat paket ditangguhkan. Pada dasarnya jika Anda memberi tahu use-packagekondisi di mana Anda membutuhkan paket ini, ia menganggap Anda tidak ingin memuatnya sampai persyaratan itu muncul.

:demand Prevent deferred loading in all cases.

Pastikan paket dimuat saat startup, terlepas dari opsi apa yang telah Anda tentukan.

Memperbarui

Meninjau kembali ini berdasarkan pada komentar baru-baru ini ... Apa yang saya katakan di atas adalah benar, tetapi saya tidak berpikir dengan benar menjawab pertanyaan. Masalah root di sini sebenarnya html-modebukan paket, melainkan mode yang ditentukan oleh paket sgml-mode. Ini berfungsi seperti yang diharapkan untuk saya:

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

Dalam contoh asli, :configekspresi tidak pernah dievaluasi karena paket bernama html-modetidak pernah dimuat. Memindahkan ekspresi yang sama menjadi :initberfungsi karena kode init selalu dievaluasi, terlepas dari apakah paket tersebut pernah dimuat.

glukas
sumber
@npostavs Terima kasih, perlu dicatat. Saya belum pindah untuk menggunakan-paket 2.0 sendiri. Untuk satu hal, saya menggunakan :idlecukup luas dan belum melihat dampak ": idle telah dihapus".
glucas
1
Saya masih tidak mengerti mengapa, ketika dia mengunjungi file HTML dan memicu paket untuk memuat, auto-filltidak dimatikan, yaitu kode konfigurasi tidak berjalan. Saya memiliki masalah yang sama.
Ken Williams
@ KenWilliams Masalah Anda dengan html-mode juga? Saya pikir masalah sebenarnya di sini adalah bahwa html-modeitu bukan paket. Setidaknya dalam versi Emacs saya saat ini, html-modedidefinisikan dalam paket sgml-mode. Jadi jika Anda mengatakan use-packageuntuk melakukan sesuatu ketika paket bernama html-modedimuat kode itu tidak pernah berjalan karena tidak ada paket seperti itu pernah dimuat Anda harus meletakkan pengaturan mode html di a (use-package sgml-mode ....).
glucas
Maaf - masalah saya dengan org-mode, bukan html-mode. Masalah serupa di sana adalah bahwa paket dipanggil org-mode, tetapi paket ELPA disebut org. Mungkin itu membingungkan (atau saya)?
Ken Williams
7

Contoh ini membuat saya lebih mudah memahami perbedaan antara :initdan :config. Mari kita ambil contoh ace-windowpaket (tetapi ini bisa berupa paket apa saja). Letakkan ini di init.elfile Anda :

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

Sekarang buka emacs Anda dan lihat di *Messages*buffer untuk melihat apakah ada hello worldpesan. Anda tidak akan dapat menemukannya karena paket ditangguhkan. Sekarang ubah dari configmenjadi init:

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

Sekarang tutup dan buka kembali emacs dan periksa *Messages*buffer. Anda akan melihat pesan itu ace window: hello worldkarena kode dijalankan apa pun yang :initdiberikan. Dalam hal configini hanya akan berjalan ketika paket itu dimuat.

Sibi
sumber
itu membantu, hanya pertanyaan sampingan, apa bedanya antara kata kunci :initdan :prefaceberdasarkan contoh Anda?
gelar doktor
@doctorate: :prefacedijalankan bahkan jika paket tersebut dinonaktifkan sedangkan :inithanya dijalankan ketika paket diaktifkan.
bbenne10