每个主模式命令在执行完毕时,都应运行与模式无关的通用钩子 change-major-mode-after-body-hook、自身的模式钩子,以及通用钩子 after-change-major-mode-hook。
这一过程通过调用 run-mode-hooks 实现。如果该主模式是派生模式,即在其内部调用了另一个主模式(父模式),则应将相关代码放在 delay-mode-hooks 内部,以避免父模式自行运行这些钩子。
取而代之,由派生模式调用的 run-mode-hooks 会一并运行父模式的钩子。See 主模式编码规范。
Emacs 22 之前的版本不包含 delay-mode-hooks。24 之前的版本不包含 change-major-mode-after-body-hook。
如果用户实现的主模式未使用 run-mode-hooks,也未更新以支持这些新特性,就无法完全遵循上述规范:它们可能过早运行父模式的钩子,或未能运行 after-change-major-mode-hook。
这会产生不良后果,例如导致使用 define-globalized-minor-mode 定义的全局次要模式无法在使用这类主模式的缓冲区中启用。
如果你遇到此类主模式,建议修正其实现以遵循规范。
当你使用 define-derived-mode 定义主模式时,会自动确保遵循上述规范。
如果不使用 define-derived-mode 而“手动”定义主模式,则可使用下面的函数来自动处理这些规范。
主模式应使用该函数运行其模式钩子。它与 run-hooks 类似(see 钩子),但还会运行 change-major-mode-after-body-hook、hack-local-variables(当缓冲区关联文件时)(see 文件局部变量)以及 after-change-major-mode-hook。
该函数最后会执行父模式中声明的 :after-hook 代码(see 定义派生模式)。
若在 delay-mode-hooks 代码块执行期间调用该函数,它不会立即运行钩子、执行 hack-local-variables 或求值相关代码,而是将这些操作推迟到 delay-mode-hooks 结束后的下一次 run-mode-hooks 调用时统一执行。
当一个主模式命令调用另一个主模式时,应将调用逻辑放在 delay-mode-hooks 内部。
该宏会执行 body,但会告知执行期间所有 run-mode-hooks 调用暂缓运行钩子。
这些钩子会在 delay-mode-hooks 结构结束后的下一次 run-mode-hooks 调用时实际运行。
这是由 run-mode-hooks 运行的通用钩子,执行时机在模式钩子之前。
这是由 run-mode-hooks 运行的通用钩子,在每个规范实现的主模式命令最后执行。