From c05e61536ed9faaef5fe6f7f4351ffb3ab15cc87 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 6 Sep 2022 19:54:16 +0200 Subject: [PATCH] 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). --- bin/doom | 42 +++++++++++++++++++----------------------- early-init.el | 15 ++++++++++----- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/bin/doom b/bin/doom index d6c4988a5..266ad5534 100755 --- a/bin/doom +++ b/bin/doom @@ -74,19 +74,20 @@ ;; - The user may have a noexec flag set on /tmp, so pass the exit script to ;; /bin/sh rather than executing them directly. -;; Ensure Doom runs out of this file's parent directory (or $EMACSDIR), where -;; Doom is presumably installed. -(setq user-emacs-directory - (if (getenv-internal "EMACSDIR") - (file-name-as-directory - (file-truename (getenv-internal "EMACSDIR"))) - (expand-file-name - "../" (file-name-directory (file-truename load-file-name))))) - - -;; -;;; Sanity checks +;; Doom's core sets up everything we need; including `doom-*-dir' variables, +;; universal defaults, and autoloads for doom-*-initialize functions. +(condition-case e + (let ((load-prefer-newer t)) + (load (expand-file-name + "../early-init" (file-name-directory (file-truename load-file-name))) + nil 'nomessage)) + ;; Prevent ugly backtraces for trivial errors + (user-error (message "Error: %s" (cadr e)) + (kill-emacs 2))) +;; 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) ;; If ~/.emacs.d is owned by root, assume the user genuinely wants root to be ;; their primary user, otherwise complain. @@ -104,16 +105,6 @@ (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 @@ -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"))) ;; It'd be simple to just load these files directly, but because there could diff --git a/early-init.el b/early-init.el index 4c1cc7970..69fde9358 100644 --- a/early-init.el +++ b/early-init.el @@ -24,9 +24,12 @@ ;; stuttering/freezes. (setq gc-cons-threshold most-positive-fixnum) -;; Prioritize old byte-compiled source files over newer sources. It saves us a -;; little IO time to skip all the mtime checks on each lookup. -(setq load-prefer-newer nil) +(eval-and-compile + ;; PERF: Don't use precious startup time checking mtime on elisp bytecode. + ;; 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) init-file-debug) @@ -85,7 +88,7 @@ (when initdir ;; Discard the switch to prevent "invalid option" errors later. (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)) (getenv-internal "DOOMPROFILE")))) @@ -136,7 +139,9 @@ ;; Load the heart of Doom Emacs (if (require 'doom (expand-file-name "lisp/doom" user-emacs-directory) t) ;; ...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. (setq early-init-file (expand-file-name "early-init" user-emacs-directory)) (load early-init-file t (not init-file-debug)))