eval-after-load vs. mode hook

75

Gibt es einen Unterschied zwischen dem Einstellen von Dingen für einen Modus mit eval-after-loadund mit dem Modus-Hook?

Ich habe einen Code gesehen, define-keyder in einem Hauptmodus-Hook verwendet wird, und einen anderen Code, define-keyder in eval-after-loadForm verwendet wird.


Aktualisieren:

Zum besseren Verständnis finden Sie hier ein Beispiel für die Verwendung von eval-after-load- und mode-Hooks mit org-mode. Der Code kann vor (load "org") oder (require 'org)oder ausgeführt werden (package-initialize).

;; The following two lines of code set some org-mode options.
;; Usually, these can be outside (eval-after-load ...) and work.
;; In cases that doesn't work, try using setq-default or set-variable
;; and putting them in (eval-after-load ...), if the
;; doc for the variables don't say what to do.
;; Or use Customize interface.
(setq org-hide-leading-stars t)
(setq org-return-follows-link t)

;; "org" because C-h f org-mode RET says that org-mode is defined in org.el
(eval-after-load "org"
  '(progn
     ;; Establishing your own keybindings for org-mode.
     ;; Variable org-mode-map is available only after org.el or org.elc is loaded.
     (define-key org-mode-map (kbd "<C-M-return>") 'org-insert-heading-respect-content)
     (define-key org-mode-map (kbd "<M-right>") nil) ; erasing a keybinding.
     (define-key org-mode-map (kbd "<M-left>") nil) ; erasing a keybinding.

     (defun my-org-mode-hook ()
       ;; The following two lines of code is run from the mode hook.
       ;; These are for buffer-specific things.
       ;; In this setup, you want to enable flyspell-mode
       ;; and run org-reveal for every org buffer.
       (flyspell-mode 1)
       (org-reveal))
     (add-hook 'org-mode-hook 'my-org-mode-hook)))
Yoo
quelle
6
+1 für "org", da Ch f org-mode RET besagt, dass org-mode in org.el definiert ist . Ich hatte Mühe, eval-after-loadtatsächlich zu bewerten nxml-mode, und dieser Tipp hat funktioniert!
Zach Young

Antworten:

106

Eingehüllter Code eval-after-loadwird nur einmal ausgeführt. Daher wird er normalerweise verwendet, um einmalige Einstellungen vorzunehmen, z. B. das Festlegen globaler Standardwerte und -verhalten. Ein Beispiel könnte das Einrichten einer Standard-Keymap für einen bestimmten Modus sein. Im eval-after-loadCode gibt es keine Vorstellung vom "aktuellen Puffer".

Modus-Hooks werden für jeden Puffer, in dem der Modus aktiviert ist, einmal ausgeführt, sodass sie für die Konfiguration pro Puffer verwendet werden. Modus-Hooks werden daher später als eval-after-loadCode ausgeführt. Auf diese Weise können sie Aktionen ausführen, die auf Informationen basieren, z. B. ob andere Modi im aktuellen Puffer aktiviert sind.

sanityinc
quelle
1
Nebenbei bemerkt (korrigieren Sie mich, wenn ich falsch liege): Der Emacs-Lisp-Modus und der Lisp-Modus scheinen geladen zu werden, bevor benutzerdefinierte Eval-After-Load-Skripte ausgeführt werden. In diesem Fall muss möglicherweise tatsächlich ein Modus-Hook verwendet werden.
Balu
1
Ja: Der eval-after-loadBlock ist immer eval‚d nach der zugehörigen Bibliothek loaded. Beachten Sie jedoch, dass der Code immer ausgeführt wird, bevor Funktionen in der zugehörigen Bibliothek aufgerufen werden. Wenn Sie dies tun, wird (eval-after-load 'lisp-mode ...)der ...Code in diesem Block ausgeführt, bevor die lisp-modeFunktion in lisp-mode.elaufgerufen wird.
Sanityinc
1
Was macht after-loadgenau? Gibt es einen Unterschied zu eval-after-load?
Balu
6
Es ist nur ein lokaler Makro-Wrapper für eval-after-load, um zu vermeiden, dass das übergebene Formular in Anführungszeichen gesetzt werden muss eval-after-load. dh. anstatt (eval-after-load 'foo '(progn (foo) (bar)))kann ich schreiben (after-load 'foo (foo) (bar)).
Sanityinc
2
@balu: emacs-lisp-modeund lisp-modewerden mit Emacs abgeladen und nie geladen.
SDS