Di mana saya harus memasukkan inisialisasi malas?

13

Saya ingin menambahkan kunci spesifik yang mengikat ke mode lateks:

(define-key latex-mode-map (kbd "<f6>") 'my-latex-defun)

Pada saat yang sama saya ingin mengaturnya hanya ketika mode spesifik dimuat. Jadi saya ingin tahu apakah ada preferensi (praktik terbaik) antara menggunakan kait yang sesuai ( latex-mode-hook) untuk mencapai itu atau menggunakan klausa (with-eval-after-load "tex-mode" ...untuk membungkus definisi pengikatan kunci. Saya menguji keduanya dan mereka bekerja dengan baik, namun saya bertanya-tanya mana yang tepat untuk melakukannya.

jrbalderrama
sumber
2
with-eval-after-loaddimuat sekali , jadi perubahan keymap pergi ke sana. Kait dimuat setiap kali mode dijalankan , misalnya saat memuat file baru yang terkait dengan mode, atau bagaimanapun kait ditentukan. Anda akan memuat misalnya flyspell-modeatau hl-line-modedi kail. Dalam saya init.elsaya gunakan with-eval-after-loadsekitar 160 kali dan add-hook110 kali. Init malas adalah init baik (IMO).
rasmus
@rasmus terdengar seperti jawaban jika Anda punya waktu :) Perbedaan berapa kali kode dijalankan adalah yang utama untuk dipertimbangkan, menurut pendapat saya. (Itu juga satu-satunya yang bisa saya pikirkan ...)
Sean Allred
Untuk alasan mengapa itu adalah ide yang buruk untuk mengubah ikatan utama dalam kait mode lihat emacs.stackexchange.com/questions/990/…
tarsius

Jawaban:

18

Init yang malas adalah init yang bagus.

(IMO)

Kapan harus digunakan with-eval-after-load

with-eval-after-loaddimuat sekali ketika tertentu fitur atau berkas yang pertama dimuat, sehingga keymap-perubahan jelas masuk ke dalam salah satu dari ini. Tidak sedikit karena keymap mungkin tidak diketahui pada waktu init [coba sesuatu seperti (define-key message-mode-map (kbd "C-c f") 'Footnote-add-footnote)di emacs -q]. Sebuah kait bukanlah solusi yang bagus di sini karena mengikat fungsi ke kunci setiap kali kait dimulai. Sebagai tarsius catatan, Anda dapat membaca lebih lanjut tentang mengapa tidak untuk local-set-keydi kait.

Akhirnya, perhatikan bahwa with-eval-after-loadGNU Emacs 24.4 adalah pembungkus 2 baris di eval-after-loadmana bodytidak perlu dikutip.

Kapan harus menggunakan kait

Kait adalah daftar fungsi yang dimuat setiap kali kriteria terpenuhi, misalnya mode tertentu dimulai. Penggunaan umum kait adalah untuk memuat mode minor, seperti flyspell-modeatau hl-line-mode. Misalnya (add-hook 'org-agenda-mode-hook 'hl-line-mode). Seperti yang ditunjukkan oleh Rémi , add-hookspintar dan akan melakukan hal yang benar bahkan jika variabel kait belum dimuat. Meskipun demikian, saya memiliki banyak klausa seperti berikut ini, yang mungkin diabaikan untuk perolehan kecepatan, tetapi memang memberikan rasa organisasi dan struktur ketergantungan:

(with-eval-after-load 'org-agenda
  (add-hook 'org-agenda-mode-hook 'hl-line-mode))

Mengapa menambah kait setelah org-agenda? Seperti biasa, C-h v org-agenda-mode-hook C-jmemberikan. Pengait didefinisikan org-agenda.elseperti yang ditunjukkan pada *help*.

Memuat fitur tambahan with-eval-after-load

with-eval-after-loadjuga penting untuk memuat fitur tambahan. Anda mungkin ingin sesuatu seperti (with-eval-after-load 'org (require 'org-inlinetask))memuat inlinetasks org. Untuk melihat alasannya (find-library "org-inlinetask"). Karena org-inlinetasks.elsecara langsung (require 'org), semua autoloadkesenangan yang diberikan oleh pengelola Emacs yang ramah kepada Anda akan "diabaikan" dan semuanya org.el(c)akan dimuat.

Tetapi bagaimana jika (pribadi) Anda defundiperlukan beberapa tempat? Jika Anda benar-benar pilih-pilih, Anda bisa meletakkan defuns di file lain di Anda load-pathdan menambahkan autoloadcookie, atau Anda dapat memberi tahu Emacs di mana menemukan fungsi dengan autoloadfungsi tersebut. Maka sesuatu seperti ini akan bekerja:

(autoload 'org-cdlatex-mode "org" "cdlatex mode from org.")
(with-eval-after-load "latex"
  (add-hook 'TeX-mode-hook 'org-cdlatex-mode))

Atau Anda bisa require orgseperti itu pada gilirannya akan menarikcdlatex

Dan, jujur, pembelotan pribadi tidak akan menjadi masalah bagi waktu init sebagian besar waktu. 1150 baris pembelaan pribadi (84 pembelaan) di saya init.elmenambahkan 0,02 atas vanilla Emacs.

Mengukur waktu inisialisasi

Cara mudah untuk memperkirakan waktu inisialisasi adalah

time emacs --eval "(kill-emacs)"

(patokan terhadap emacs -q.

Tetapi untuk mendapatkan perkiraan yang lebih rinci dari mana kemacetan inisialisasi periksa Joe Schafer's esup.

Akhirnya, waktu memuat tidak hilang secara ajaib. Anda hanya mendorongnya ke depan (sejauh Anda menggunakan semua fitur di setiap sesi).

rasmus
sumber
1
Anda tidak perlu memasukkan add-hook dalam with-eval-after-load, karena add-hook akan mengikat variabel jika belum ada.
Rémi
Kamu benar! Mungkinkah masih ada keuntungan kecepatan dari itu? [Saya akan mencoba memperbarui jawabannya nanti untuk mencerminkan ini]
rasmus
Bagaimana dengan defun yang nanti saya ingin ikat ke pengait atau pengikat kunci. Haruskah saya mendefinisikan pembelokan di luar with-eval-after-loadtanpa kehilangan keuntungan inisialisasi malas?
jrbalderrama
5

Selain saran Anda tentang eval-after-loaddan menggunakan kail, izinkan saya menyarankan use-package.el. Anda dapat melakukan apa yang perlu Anda lakukan

(use-package latex
  :ensure auctex
  :bind ("<f6>" . my-latex-defun))

LaTeX tidak akan dimuat sampai setelah Anda memintanya.

Sama seperti catatan tambahan: penggunaan yang teliti use-packagetelah mengurangi waktu startup saya hingga di bawah satu detik. (Dulu butuh sekitar empat detik.)

Sean Allred
sumber
Terima kasih atas saranmu. Saya juga telah merenungkan untuk menggunakan paket-pakai tetapi saya benar-benar ingin mencari tahu bagaimana melakukannya tanpa paket tambahan.
jrbalderrama
1
@jrbalderrama note yang use-packageakan dikirimkan bersama Emacs 25.
Sean Allred