2010-04-29 1 views
59

C'è una differenza tra l'impostazione di una modalità usando eval-after-load e l'utilizzo del hook della modalità?aggancio eval-after-load vs. mode

Ho visto un codice in cui define-key viene utilizzato all'interno di un hook di modalità principale e un altro codice in cui define-key viene utilizzato nel modulo eval-after-load.


Aggiornamento:

Per una migliore comprensione, ecco un esempio di utilizzo eval-post-carico e ganci modalità con org-mode. Il codice può essere eseguito prima del(load "org") o (require 'org) o (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))) 
+3

+1 per * "org" perché C-h f org-mode RET dice che l'org-mode è definito in org.el *. Stavo cercando di ottenere 'eval-after-load' per valutare effettivamente' nxml-mode', e questo trucco ha funzionato! –

risposta

84

Codice avvolto in eval-after-load verrà eseguito solo una volta, per cui è in genere utilizzato per eseguire l'impostazione di una volta come l'impostazione dei valori predefiniti globali e comportamento. Un esempio potrebbe essere la configurazione di una keymap predefinita per una modalità particolare. Nel codice eval-after-load, non esiste il concetto di "buffer corrente".

I hook di modalità vengono eseguiti una volta per ogni buffer in cui è abilitata la modalità, quindi vengono utilizzati per la configurazione per buffer. I ganci Mode vengono quindi eseguiti dopo il codice eval-after-load; ciò consente loro di intraprendere azioni basate su tali informazioni come se altre modalità siano abilitate nel buffer corrente.

+0

Nota a margine (correggimi se ho torto): emacs-lisp-mode e lisp-mode sembrano essere caricati prima che gli script personalizzati eval-after-load possano essere eseguiti. In tal caso, in effetti, potrebbe essere necessario utilizzare un hook di modalità. – balu

+1

Sì: il blocco 'eval-after-load' è sempre' eval''d * dopo * la libreria correlata è 'load'ed. Ma si noti che il codice verrà sempre eseguito * prima * vengono chiamate tutte le funzioni nella libreria correlata. Quindi se tu '(eval-after-load 'lisp-mode ...)', allora il codice '...' in questo blocco verrà eseguito prima della funzione 'lisp-mode' in' lisp-mode.el' è chiamato. – sanityinc

+0

Ci scusiamo per la formulazione. Naturalmente, le librerie vengono caricate prima di eval - ** dopo ** - il caricamento viene eseguito. Ma per quanto riguarda emacs-lisp-mode e lisp-mode non sembrano essere affatto eseguiti: ho provato a modificare le loro keymap che funzionavano bene in un hook di modalità ma non in un blocco eval-after-load (nulla sarebbe cambiato) . Con python-mode e altre modalità, tuttavia, tutto funziona correttamente. Quindi la mia ipotesi era che le modalità emacs-lisp e lisp sono eccezioni e sono in qualche modo incorporate, nel senso che vengono caricate prima che la configurazione di Emacs venga analizzata. – balu