Search code examples
emacsinitializationhookelispmajor-mode

Execution order of eval-after-load vs hooks for a given major mode in emacs


Let's assume the particular mode I'm working with is python-mode. The Emacs manual specifies following for hooks:

Every major mode command is supposed to run a normal hook called the mode hook as one of the last steps of initialization.

From Major mode conventions:

Each major mode should have a normal mode hook named modename-mode-hook. The very last thing the major mode command should do is to call run-mode-hooks.

And with-eval-after-load executes code after code is loaded (e.g. required), and runs immediately if already required.

I have following in my init file:

(add-hook 'python-mode-hook 'my-post-python)

Also I have added

    (with-eval-after-load 'python-mode
     (setq-default python-basic-offset 7) ; setting some option
     (add-to-list 'python-globals-list "console"))

Now assuming I open Emacs, followed by opening a Python file buffer, what are the loading/execution orders with respect to hooks and with-eval-after-load? From the docs specified at start, it seems mode hooks will run before with-eval-after-load code?

More specifically, are mode hooks are run every time a buffer is entered/ made the current buffer? (P.S. this is hard to find from the docs/manual, any links clarifying any of the above in the docs/manual are welcome).


Solution

  • Now assuming I open emacs, followed by opening a python file buffer, what are the loading/execution order with respect to hooks and with-eval-after-load?

    Assuming python.el has not already been loaded, then:

    • You visit foo.py.
    • set-auto-mode is called and determines that python-mode is appropriate, and calls that.
    • The python-mode function is (at this point) an autoload definition for the python-mode library1, which is consequently loaded.
    • At the end of loading, your with-eval-after-load for the python-mode library is evaluated.
    • The real python-mode function (newly defined by loading the library) is called, at the end of which:
    • python-mode-hook runs.

    Are mode hooks are run every time a buffer is entered/ made the current buffer?

    No, they run every time the mode function is called.


    1 The default library is python.el which uses (provide 'python), but from your with-eval-after-load you're evidentially using the python-mode.el library instead.