feat: add doom-{before,after}-init-hook

doom-before-init-hook runs before $DOOMDIR/init.el is loaded.

doom-after-init-hook runs at the *very* end of the Emacs startup
process (after window-setup-hook).
This commit is contained in:
Henrik Lissner 2022-09-14 19:01:57 +02:00
parent 18cd2eb483
commit 0d7c3eaf24
No known key found for this signature in database
GPG key ID: B60957CA074D39A3
4 changed files with 81 additions and 34 deletions

View file

@ -25,27 +25,22 @@
;; HACK: Load `cl' and site files manually to prevent polluting logs and
;; stdout with deprecation and/or file load messages.
(when noninteractive
(let ((inhibit-message (not init-file-debug)))
(require 'cl nil t)
(unless site-run-file
(let ((site-run-file "site-start")
(tail load-path)
(lispdir (expand-file-name "../lisp" data-directory))
dir)
(while tail
(setq dir (car tail))
(let ((inhibit-message (not init-file-debug)))
(require 'cl nil t)
(unless site-run-file
(let ((site-run-file "site-start")
(tail load-path)
(lispdir (expand-file-name "../lisp" data-directory))
dir)
(while tail
(setq dir (car tail))
(let ((default-directory dir))
(load (expand-file-name "subdirs.el") t inhibit-message t))
(unless (string-prefix-p lispdir dir)
(let ((default-directory dir))
(load (expand-file-name "subdirs.el") t inhibit-message t))
(unless (string-prefix-p lispdir dir)
(let ((default-directory dir))
(load (expand-file-name "leim-list.el") t inhibit-message t)))
(setq tail (cdr tail)))
(load site-run-file t inhibit-message)))))
;; Reset these vars' initial values, in case the site files have changed them.
(dolist (var '(exec-path load-path process-environment))
(put var 'initial-value (default-value var)))
(load (expand-file-name "leim-list.el") t inhibit-message t)))
(setq tail (cdr tail)))
(load site-run-file t inhibit-message))))
(setq-default
;; PERF: Don't generate superfluous files when writing temp buffers.
@ -79,7 +74,9 @@
;; Ensure straight and core packages are ready to go for CLI commands.
;; (require 'doom-profiles)
(require 'doom-modules)
(require 'doom-packages))
(require 'doom-packages)
;; For any last-minute initialization.
(run-hooks 'doom-before-init-hook))
;;

View file

@ -295,8 +295,8 @@ If RETURN-P, return the message as a string instead of displaying it."
;; Bootstrap the interactive session
(add-hook 'after-change-major-mode-hook #'doom-run-local-var-hooks-h 100)
(add-hook 'hack-local-variables-hook #'doom-run-local-var-hooks-h)
(add-hook 'emacs-startup-hook #'doom-load-packages-incrementally-h)
(add-hook 'window-setup-hook #'doom-display-benchmark-h 105)
(add-hook 'doom-after-init-hook #'doom-load-packages-incrementally-h)
(add-hook 'doom-after-init-hook #'doom-display-benchmark-h 110)
(doom-run-hook-on 'doom-first-buffer-hook '(find-file-hook doom-switch-buffer-hook))
(doom-run-hook-on 'doom-first-file-hook '(find-file-hook dired-initial-position-hook))
(doom-run-hook-on 'doom-first-input-hook '(pre-command-hook))
@ -310,11 +310,9 @@ If RETURN-P, return the message as a string instead of displaying it."
(eval-after-load 'straight '(doom-initialize-packages))
(require 'doom-modules)
;; Undo any problematic startup optimizations; from this point, I make no
;; assumptions about what might be loaded in userland.
(when (get 'load-suffixes 'initial-value)
(setq load-suffixes (get 'load-suffixes 'initial-value)
load-file-rep-suffixes (get 'load-file-rep-suffixes 'initial-value)))
;; A last ditch opportunity to undo dodgy optimizations or do extra
;; configuration before the session is complicated by user config and packages.
(doom-run-hooks 'doom-before-init-hook)
;; Load user config + modules
(doom-initialize-modules)

View file

@ -622,10 +622,7 @@ triggering hooks during startup."
;; Initialize `doom-switch-buffer-hook'
(add-hook 'window-buffer-change-functions #'doom-run-switch-buffer-hooks-h)
;; `window-buffer-change-functions' doesn't trigger for files visited via the server.
(add-hook 'server-visit-hook #'doom-run-switch-buffer-hooks-h)
;; Only execute this function once.
(remove-hook 'window-buffer-change-functions #'doom-init-ui-h))
(add-hook 'server-visit-hook #'doom-run-switch-buffer-hooks-h))
;; Apply fonts and theme
(let ((hook (if (daemonp)
@ -636,7 +633,7 @@ triggering hooks during startup."
;; Initialize UI as late as possible. `window-buffer-change-functions' runs
;; once, when the scratch/dashboard buffer is first displayed.
(add-hook 'window-buffer-change-functions #'doom-init-ui-h -100)
(add-hook 'doom-after-init-hook #'doom-init-ui-h -100)
;;

View file

@ -35,6 +35,7 @@
;; $EMACSDIR/early-init.el
;; $EMACSDIR/lisp/doom.el
;; $EMACSDIR/lisp/doom-start.el
;; `doom-before-init-hook'
;; $DOOMDIR/init.el
;; `doom-before-modules-init-hook'
;; {$DOOMDIR,~/.emacs.d}/modules/*/*/init.el
@ -47,6 +48,7 @@
;; `emacs-startup-hook'
;; `doom-init-ui-hook'
;; `window-setup-hook'
;; `doom-after-init-hook'
;;
;;; Code:
@ -294,7 +296,7 @@ users).")
;; `load', or various file/io functions (like `expand-file-name' or
;; `file-remote-p'). You get a noteable boost to startup time by unsetting
;; or simplifying its value.
(let ((old-value (get 'file-name-handler-alist 'initial-value)))
(let ((old-value (default-toplevel-value 'file-name-handler-alist)))
(setq file-name-handler-alist
;; HACK: If the bundled elisp for this Emacs install isn't
;; byte-compiled (but is compressed), then leave the gzip file
@ -375,12 +377,21 @@ users).")
;; PERF: `load-suffixes' and `load-file-rep-suffixes' are consulted on each
;; `require' and `load'. Doom won't load any dmodules this early, so omit
;; .so for a small startup boost. This is later restored in doom-start.
(put 'load-suffixes 'initial-value (default-toplevel-value 'load-suffixes))
(put 'load-file-rep-suffixes 'initial-value (default-toplevel-value 'load-file-rep-suffixes))
(set-default-toplevel-value 'load-suffixes '(".elc" ".el"))
(set-default-toplevel-value 'load-file-rep-suffixes '(""))
;; COMPAT: Undo any problematic startup optimizations; from this point, I make
;; no assumptions about what might be loaded in userland.
(add-hook! 'doom-before-init-hook
(defun doom--reset-load-suffixes-h ()
(setq load-suffixes (get 'load-suffixes 'initial-value)
load-file-rep-suffixes (get 'load-file-rep-suffixes 'initial-value))))
;; PERF: The mode-line procs a couple dozen times during startup. This is
;; normally quite fast, but disabling the default mode-line and reducing the
;; update delay timer seems to stave off ~30-50ms.
(put 'mode-line-format 'initial-value (default-toplevel-value 'mode-line-format))
(setq-default mode-line-format nil)
(dolist (buf (buffer-list))
(with-current-buffer buf (setq mode-line-format nil)))
@ -508,5 +519,49 @@ Otherwise, `en/disable-command' (in novice.el.gz) is hardcoded to write them to
;; compatibility fallbacks
"gnutls-cli -p %p %h"))
;;
;;; Custom hooks
(defcustom doom-before-init-hook ()
"A hook run before Doom has been initialized and before $DOOMDIR/init.el.
This occurs in the context of early-init.el. Much of Emacs and Doom isn't
initialized at this point, only loaded. Use this for configuration at the latest
opportunity before the session becomes unpredictably complicated by user config,
packages, etc.
Do not use this for interactive functionality, as it's triggered in
noninteractive sessions as well, after Doom core has been loaded, but not
initialized.
In contrast, `before-init-hook' is run just after $DOOMDIR/init.el is loaded,
but before the rest of Doom is loaded."
:group 'doom
:type 'hook)
(defcustom doom-after-init-hook ()
"A hook run at the (true) end of Emacs startup.
When this runs, all modules, config files, and startup hooks have been
triggered. This is the absolute latest point in the startup process."
:group 'doom
:type 'hook)
;;
;;; Last minute initialization
(add-hook! 'doom-before-init-hook
(defun doom--set-initial-values-h ()
;; Remember these variables' initial values, so we can safely reset them at
;; a later time, or consult them without fear of contamination.
(dolist (var '(exec-path load-path process-environment))
(put var 'initial-value (default-toplevel-value var)))))
;; This is the absolute latest a hook can run in Emacs' startup process.
(define-advice command-line-1 (:after (&rest _) run-after-init-hook)
(doom-run-hooks 'doom-after-init-hook))
(provide 'doom)
;;; doom.el ends here