Tôi nên bao gồm một khởi tạo lười biếng ở đâu?


13

Tôi muốn thêm một ràng buộc khóa cụ thể vào chế độ latex:

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

Đồng thời tôi chỉ muốn đặt nó khi chế độ cụ thể được tải. Vì vậy, tôi muốn biết liệu có một ưu tiên (thực tiễn tốt nhất) giữa việc sử dụng hook ( latex-mode-hook) thích hợp để thực hiện điều đó hay sử dụng mệnh đề (with-eval-after-load "tex-mode" ...để bọc định nghĩa ràng buộc chính. Tôi đã thử nghiệm cả hai và chúng hoạt động tốt, tuy nhiên tôi tự hỏi cái nào là đúng cách để làm điều đó.


2
with-eval-after-loadđược tải một lần , do đó, một thay đổi sơ đồ sẽ xuất hiện ở đó. Móc tải mỗi khi chế độ được chạy , ví dụ như khi tải một tệp mới được liên kết với chế độ, hoặc tuy nhiên móc được xác định. Bạn sẽ tải ví dụ flyspell-modehoặc hl-line-modetrong một cái móc. Trong tôi init.elsử dụng with-eval-after-loadkhoảng 160 lần và add-hook110 lần. Một init lười biếng là một init tốt (IMO).
rasmus

@rasmus nghe có vẻ như là một câu trả lời nếu bạn có thời gian :) Theo tôi, sự khác biệt về số lần mã được chạy là cái chính để xem xét, theo ý kiến ​​của tôi. (Đây cũng là người duy nhất tôi có thể nghĩ về sự kiện)
Sean Allred

Để biết lý do tại sao nên thay đổi các ràng buộc chính trong móc chế độ, xem emacs.stackexchange.com/questions/990/iêu
tarsius

Câu trả lời:


18

Một init lười biếng là một init tốt.

(IMO)

Khi nào sử dụng with-eval-after-load

with-eval-after-loadđược tải một lần khi một tính năng hoặc tệp nhất định được tải lần đầu tiên , do đó, thay đổi sơ đồ bàn phím rõ ràng nằm trong một trong những tính năng này. Không phải là ít nhất bởi vì sơ đồ bàn phím có thể không được biết vào lúc bắt đầu [thử một cái gì đó như (define-key message-mode-map (kbd "C-c f") 'Footnote-add-footnote)trong emacs -q]. Một móc chưa là thoải mái giải pháp ở đây vì nó liên kết với các chức năng để một chìa khóa mỗi lần móc được bắt đầu. Như tarsius ghi chú, bạn có thể đọc thêm về việc tại sao không để local-set-keytrong móc.

Cuối cùng, lưu ý rằng with-eval-after-loadGNU Emacs 24.4 là trình bao bọc 2 dòng xung quanh eval-after-loadnơi bodykhông cần trích dẫn.

Khi nào sử dụng móc

Móc là danh sách các chức năng được tải mỗi khi một tiêu chí được đáp ứng, ví dụ: một chế độ nhất định được bắt đầu. Một cách sử dụng phổ biến của hook là để tải các chế độ nhỏ, chẳng hạn như flyspell-modehoặc hl-line-mode. Ví dụ (add-hook 'org-agenda-mode-hook 'hl-line-mode). Như Rémi chỉ ra, add-hookslà thông minh và sẽ làm đúng ngay cả khi biến hook chưa được tải. Tuy nhiên, tôi có nhiều mệnh đề như sau, có thể không đáng kể để tăng tốc, nhưng lại mang lại ý nghĩa về tổ chức và cấu trúc phụ thuộc:

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

Tại sao thêm vào hook sau org-agenda? Như mọi khi, C-h v org-agenda-mode-hook C-jcung cấp. Các hook được định nghĩa org-agenda.elnhư thể hiện trong *help*.

Đang tải các tính năng bổ sung with-eval-after-load

with-eval-after-loadcũng quan trọng để tải các tính năng bổ sung. Bạn có thể muốn một cái gì đó như (with-eval-after-load 'org (require 'org-inlinetask))tải org inlinet Nhiệm vụ. Để xem tại sao (find-library "org-inlinetask"). Vì org-inlinetasks.eltrực tiếp (require 'org), tất cả những điều tốt đẹp autoloadmà những người bảo trì Emacs thân thiện của bạn rất quan tâm để cung cấp sẽ bị "bỏ qua" và tất cả org.el(c)sẽ được tải.

Nhưng nếu (cá nhân) của bạn defunđược yêu cầu một vài nơi thì sao? Nếu bạn thực sự kén chọn, bạn có thể đặt defuns vào một tệp khác trong tệp của mình load-pathvà thêm autoloadcookie hoặc bạn có thể cho Emacs biết nơi tìm hàm với autoloadhàm. Sau đó, một cái gì đó như thế này sẽ làm việc:

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

Hoặc bạn có thể require orglần lượt kéo nócdlatex

Và, thành thật mà nói, việc giải tán cá nhân sẽ không còn quan trọng đối với thời gian khởi đầu. 1150 dòng defun cá nhân (84 defun) trong tôi init.elthêm 0,02s so với vanilla Emacs.

Đo thời gian khởi tạo

Một cách dễ dàng để ước tính thời gian xác định là

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

(điểm chuẩn so với emacs -q.

Nhưng để có được một xấp xỉ chi tiết hơn về nơi mà các nút thắt khởi tạo được kiểm tra của Joe Schafer esup.

Cuối cùng, thời gian tải không biến mất một cách kỳ diệu. Bạn chỉ đẩy nó về phía trước (đến phần mở rộng mà bạn sử dụng tất cả các tính năng trong mỗi phiên).


1
Bạn không cần đặt add-hook trong một tải sau khi tải, bởi vì add-hook sẽ liên kết biến nếu nó chưa có ở đó.
Rémi

Bạn đúng rồi! Có thể vẫn có tốc độ tăng từ nó mặc dù? [Tôi sẽ cố gắng cập nhật câu trả lời sau để phản ánh điều này]
rasmus

Điều gì về defun mà sau này tôi muốn liên kết với một hook hoặc ràng buộc khóa. Tôi có nên xác định một defun bên ngoài with-eval-after-loadmà không mất các lợi thế khởi tạo lười biếng?
jrbalderrama

5

Ngoài các đề xuất của bạn về eval-after-loadvà sử dụng một cái móc, hãy để tôi đề nghị use-package.el. Bạn có thể làm những gì bạn cần với

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

LaTeX sẽ không được tải cho đến khi bạn yêu cầu.

Cũng như một lưu ý phụ: việc sử dụng cẩn thận use-packageđã cắt giảm thời gian khởi động của tôi xuống dưới một giây. (Nó thường mất khoảng bốn giây.)


Cảm ơn bạn đã gợi ý. Tôi cũng đã dự tính sử dụng gói sử dụng nhưng tôi thực sự muốn tìm ra cách thực hiện mà không cần các gói bổ sung.
jrbalderrama

1
@jrbalderrama lưu ý use-packageđược thiết lập để giao hàng với Emacs 25.
Sean Allred
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.