何时在Emacs中使用add-hook,eval-after-load

1am*_*bda 1 emacs hook major-mode eval-after-load

我读过eval-after-load和add-hook.根据页面,代码输入eval-after-load执行一次.
另一方面,add-hook每次打开该模式的缓冲区时,内部代码都会运行.

好.但是,如何确定哪些代码应该在eval-after-load块或add-hook块内?例如,

(eval-after-load "js2-mode"
  '(progn
      (js2-basic-offset 2)))
Run Code Online (Sandbox Code Playgroud)

要么

(eval-after-load "js2-mode"
  '(progn
      (defun custom:js2-config ()
        (js2-basic-offset 2))
      (add-hook 'js2-mode-hook 'custom:js2-config)))
Run Code Online (Sandbox Code Playgroud)

我不是在问js2-basic-offset.
有一般规则吗?或..每当我使用时eval-after-load,我都要问?

Gil*_*il' 5

您是在设置全局变量还是局部变量?

如果您正在设置缓冲区局部变量(其值在不同缓冲区中可能不同),则必须在加载文件后执行,因此在主模式挂钩中.如果您正在调用对当前缓冲区有影响的函数,则会发生同样的情况.

如果您正在设置一个全局变量,那么在模式挂钩中执行此操作是没有意义的:每当您碰巧以特定模式加载文件时,您将更改全局变量.如果您正在调用影响全局设置的函数,则会发生同样的情况.

许多全局变量可以直接在您的设置中设置.emacs,而无需等待将声明并使用它的库加载.事实上,这通常是全局变量的情况.

js2-basic-offset是一个变量,而不是一个函数.如果你想配置中的所有JS缓冲区压痕,直接在你的设置.emacs,无论是与

(setq js2-basic-offset 2)
Run Code Online (Sandbox Code Playgroud)

或通过自定义界面.

如果你想在不同的文件中设置不同的值,那么你可以在主模式钩子中设置它 - 类似于

(defun custom:js2-config ()
  (when (…)
    (make-local-variable 'js2-basic-offset)
    (setq js2-basic-offset 2)))
(add-hook 'js2-mode-hook 'custom:js2-config)
Run Code Online (Sandbox Code Playgroud)

您无需等待加载库以添加挂钩.

请注意,Emacs具有内置工具,涵盖了基于每个文件或每个项目设置变量的典型用例:文件局部变量目录局部变量.