1. ホーム
  2. emacs

eval-after-load vs. mode hook

2023-07-26 04:07:42

質問

モードに対する設定は eval-after-load を使って設定するのと、モードフックを使って設定するのとでは、何か違いがあるのでしょうか?

私はいくつかのコードを見てきました。 define-key がメジャーモードフックの中で使われているコードや、他のコードで define-key の中で使われている eval-after-load の形で使用されます。


更新してください。

理解を深めるために、org-modeでeval-after-loadとmode hooksを使う例を示します。このコードでは の前に (load "org") または (require 'org) または (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)))

どのように解決するのですか?

で囲んだコード eval-after-load は一度しか実行されないので、通常はデフォルトのグローバルな値や動作を設定するような一回限りの設定を行うために使用されます。例えば、特定のモードのためのデフォルトのキーマップを設定するようなものです。この場合 eval-after-load コードでは、"カレントバッファ" という概念はありません。

モードフックはモードが有効になっている全てのバッファに対して一度だけ実行されるので、 バッファごとの設定に使われます。そのため、モードフックはバッファごとの設定に使われます。 eval-after-load コードよりも後に実行されます; これにより、現在のバッファで他のモードが有効になっているかどうかなどの情報に基づいてアクションを取ることができます。