refactor: make early-init.el Doom's universal bootstrapper

This centralizes Doom's core startup optimizations and, as a
side-effect, reduces the runtime of bin/doom commands substantially.
This also simplifies the user story for loading Doom remotely (for batch
sessions or doomscripts).
This commit is contained in:
Henrik Lissner 2022-09-06 19:54:16 +02:00
parent 3853dff5e1
commit c05e61536e
No known key found for this signature in database
GPG key ID: B60957CA074D39A3
2 changed files with 29 additions and 28 deletions

View file

@ -74,19 +74,20 @@
;; - The user may have a noexec flag set on /tmp, so pass the exit script to ;; - The user may have a noexec flag set on /tmp, so pass the exit script to
;; /bin/sh rather than executing them directly. ;; /bin/sh rather than executing them directly.
;; Ensure Doom runs out of this file's parent directory (or $EMACSDIR), where ;; Doom's core sets up everything we need; including `doom-*-dir' variables,
;; Doom is presumably installed. ;; universal defaults, and autoloads for doom-*-initialize functions.
(setq user-emacs-directory (condition-case e
(if (getenv-internal "EMACSDIR") (let ((load-prefer-newer t))
(file-name-as-directory (load (expand-file-name
(file-truename (getenv-internal "EMACSDIR"))) "../early-init" (file-name-directory (file-truename load-file-name)))
(expand-file-name nil 'nomessage))
"../" (file-name-directory (file-truename load-file-name))))) ;; Prevent ugly backtraces for trivial errors
(user-error (message "Error: %s" (cadr e))
(kill-emacs 2)))
;;
;;; Sanity checks
;; UX: Abort if the user is using 'doom' as root, unless ~/.emacs.d is owned by
;; root, in which case we assume the user genuinely wants root to be their
;; primary user account for Emacs.
(when (equal (user-real-uid) 0) (when (equal (user-real-uid) 0)
;; If ~/.emacs.d is owned by root, assume the user genuinely wants root to be ;; If ~/.emacs.d is owned by root, assume the user genuinely wants root to be
;; their primary user, otherwise complain. ;; their primary user, otherwise complain.
@ -104,16 +105,6 @@
(kill-emacs 2))) (kill-emacs 2)))
;;
;;; Load Doom's CLI framework
(require 'doom-cli (expand-file-name "lisp/doom-cli" user-emacs-directory))
;; Load $DOOMDIR/init.el, to read the user's `doom!' block, and so users can
;; customize things early, if they like.
(load! doom-module-init-file doom-user-dir t)
;; ;;
;;; Entry point ;;; Entry point
@ -237,7 +228,12 @@ SEE ALSO:
;; ;;
;;; Commands ;;; Load user config + commands
;; Load $DOOMDIR/init.el, to read the user's `doom!' block and give users an
;; opportunity to customize the CLI environment, if they like. Otherwise, they
;; can do so in .doomrc or .doomproject.
(load! doom-module-init-file doom-user-dir t)
(let ((dir (doom-path doom-core-dir "cli"))) (let ((dir (doom-path doom-core-dir "cli")))
;; It'd be simple to just load these files directly, but because there could ;; It'd be simple to just load these files directly, but because there could

View file

@ -24,9 +24,12 @@
;; stuttering/freezes. ;; stuttering/freezes.
(setq gc-cons-threshold most-positive-fixnum) (setq gc-cons-threshold most-positive-fixnum)
;; Prioritize old byte-compiled source files over newer sources. It saves us a (eval-and-compile
;; little IO time to skip all the mtime checks on each lookup. ;; PERF: Don't use precious startup time checking mtime on elisp bytecode.
(setq load-prefer-newer nil) ;; Ensuring correctness is 'doom sync's job, not the interactive session's.
;; Still, stale byte-code will cause *heavy* losses in startup efficiency.
(setq load-prefer-newer noninteractive))
(unless (or (daemonp) (unless (or (daemonp)
init-file-debug) init-file-debug)
@ -85,7 +88,7 @@
(when initdir (when initdir
;; Discard the switch to prevent "invalid option" errors later. ;; Discard the switch to prevent "invalid option" errors later.
(add-to-list 'command-switch-alist (cons "--init-directory" (lambda (_) (pop argv)))) (add-to-list 'command-switch-alist (cons "--init-directory" (lambda (_) (pop argv))))
(setq user-emacs-directory initdir))) (setq user-emacs-directory (expand-file-name initdir))))
(let ((profile (or (cadr (member "--profile" command-line-args)) (let ((profile (or (cadr (member "--profile" command-line-args))
(getenv-internal "DOOMPROFILE")))) (getenv-internal "DOOMPROFILE"))))
@ -136,7 +139,9 @@
;; Load the heart of Doom Emacs ;; Load the heart of Doom Emacs
(if (require 'doom (expand-file-name "lisp/doom" user-emacs-directory) t) (if (require 'doom (expand-file-name "lisp/doom" user-emacs-directory) t)
;; ...and prepare for an interactive session. ;; ...and prepare for an interactive session.
(setq init-file (expand-file-name "doom-start" doom-core-dir)) (if noninteractive
(require 'doom-cli)
(setq init-file (expand-file-name "doom-start" doom-core-dir)))
;; ...but if that fails, then this is likely not a Doom config. ;; ...but if that fails, then this is likely not a Doom config.
(setq early-init-file (expand-file-name "early-init" user-emacs-directory)) (setq early-init-file (expand-file-name "early-init" user-emacs-directory))
(load early-init-file t (not init-file-debug))) (load early-init-file t (not init-file-debug)))