refactor!: complete profile gen and init systems
BREAKING CHANGE: This commit makes three breaking changes: - Doom now fully and dynamically generates (and byte-compiles) your profile and its init files, which includes your autoloads, loading your init files and modules, and then some. This replaces doom-initialize-modules, doom-initialize-core-modules, and doom-module-loader, which have been removed. This has also improved startup time by a bit, but if you use these functions in your CLIs, for instance, this will be a breaking change. - `doom sync` is now required for Doom to see your profiles (and must be run whenever you change them, or when you up/downgrade Emacs across major versions). - $DOOMDIR/init.el is now read much earlier than it used to be. Before any of doom-{ui,keybinds,editor,projects}, before any autoloads are loaded, and before your load-path has been populated with your packages. It now runs in the context of early-init.el, giving users freer range over what they can affect, but a more minimalistic environment to do it in. If you must have some logic run when all that is set up, add it to one of the module hooks added in e08f68b or 283308a. This also poses a significant change to Doom's load order (see the commentary change in lib/doom.el), along with the following (non breaking) changes: 1. Adds a new `doom profiles sync` command. This will forcibly resync your profiles, while `doom sync` will only do so if your profiles have changed. 2. Doom now fully and dynamically generates (and byte-compiles) your user-init-file, which includes loading all your init files, modules, and custom-file. This replaces the job of doom-initialize-modules, doom-initialize-core-modules, and doom-module-loader, which have been removed. This has also improved startup time by a bit. 3. Defines new doom-state-dir variable, though not used yet (saving that and the other breaking changes for the 3.0 release). 4. Redesigns profile directory variables (doom-profile-*-dir) to prepare for future XDG-compliance. 5. Removed unused/unimportant profile variables in doom.el. 6. Added lisp/doom-profiles.el. It's hardly feature complete, but it's enough to power the system as it is now. 7. Updates the "load order" commentary in doom.el to reflect these changes.
This commit is contained in:
parent
3d6e0311b9
commit
b914830403
15 changed files with 981 additions and 402 deletions
|
@ -246,28 +246,6 @@ If RETURN-P, return the message as a string instead of displaying it."
|
|||
;;
|
||||
;;; Let 'er rip!
|
||||
|
||||
;;; Load loaddefs
|
||||
;; Doom caches a lot of information in `doom-autoloads-file'. Module and package
|
||||
;; autoloads, autodefs like `set-company-backend!', and variables like
|
||||
;; `doom-modules', `doom-disabled-packages', `load-path', `auto-mode-alist', and
|
||||
;; `Info-directory-list'. etc. Compiling them into one place is a big reduction
|
||||
;; in startup time.
|
||||
(condition-case-unless-debug e
|
||||
;; Avoid `file-name-sans-extension' for premature optimization reasons.
|
||||
;; `string-remove-suffix' is cheaper because it performs no file sanity
|
||||
;; checks; just plain ol' string manipulation.
|
||||
(load (string-remove-suffix ".el" doom-autoloads-file) nil 'nomessage)
|
||||
(file-missing
|
||||
;; If the autoloads file fails to load then the user forgot to sync, or
|
||||
;; aborted a doom command midway!
|
||||
(if (locate-file doom-autoloads-file load-path)
|
||||
;; Something inside the autoloads file is triggering this error;
|
||||
;; forward it to the caller!
|
||||
(signal 'doom-autoload-error e)
|
||||
(signal 'doom-error
|
||||
(list "Doom is in an incomplete state"
|
||||
"run 'doom sync' on the command line to repair it")))))
|
||||
|
||||
;;; Load envvar file
|
||||
;; 'doom env' generates an envvar file. This is a snapshot of your shell
|
||||
;; environment, which Doom loads here. This is helpful in scenarios where Emacs
|
||||
|
@ -278,7 +256,23 @@ If RETURN-P, return the message as a string instead of displaying it."
|
|||
(setq-default process-environment (get 'process-environment 'initial-value))
|
||||
(doom-load-envvars-file doom-env-file 'noerror))
|
||||
|
||||
;; Bootstrap the interactive session
|
||||
;;; Load core modules and set up their autoloads
|
||||
(require 'doom-modules)
|
||||
(autoload 'doom-initialize-packages "doom-packages")
|
||||
;; TODO (autoload 'doom-profiles-initialize "doom-profiles")
|
||||
;; TODO (autoload 'doom-packages-initialize "doom-packages")
|
||||
|
||||
;; UX: There's a chance the user will later use package.el or straight in this
|
||||
;; interactive session. If they do, make sure they're properly initialized
|
||||
;; when they do.
|
||||
(with-eval-after-load 'package (require 'doom-packages))
|
||||
(with-eval-after-load 'straight (doom-initialize-packages))
|
||||
|
||||
;; 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)
|
||||
|
||||
;;; Last minute setup
|
||||
(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 'doom-after-init-hook #'doom-load-packages-incrementally-h)
|
||||
|
@ -287,21 +281,96 @@ If RETURN-P, return the message as a string instead of displaying it."
|
|||
(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))
|
||||
|
||||
;;; Setup autoloads for major core libraries
|
||||
;; UX: There's a chance the user will later use package.el or straight in this
|
||||
;; interactive session. If they do, make sure they're properly initialized
|
||||
;; when they do.
|
||||
(autoload 'doom-initialize-packages "doom-packages")
|
||||
(eval-after-load 'package '(require 'doom-packages))
|
||||
(eval-after-load 'straight '(doom-initialize-packages))
|
||||
(require 'doom-modules)
|
||||
;;; Load $DOOMDIR/init.el early
|
||||
;; TODO: Catch errors
|
||||
(doom-load (file-name-concat doom-user-dir doom-module-init-file) t)
|
||||
|
||||
;; 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 the rest of $DOOMDIR + modules if noninteractive
|
||||
;; If the user is loading this file from a batch script, let's assume they want
|
||||
;; to load their userland config as well.
|
||||
(when noninteractive
|
||||
(doom-require 'doom-profiles)
|
||||
(let ((init-file (doom-profile-init-file)))
|
||||
(unless (file-exists-p init-file)
|
||||
(user-error "Profile init file hasn't been generated. Did you forgot to run 'doom sync'?"))
|
||||
(let (kill-emacs-query-functions
|
||||
kill-emacs-hook)
|
||||
;; Loads modules, then $DOOMDIR/config.el
|
||||
(doom-load init-file 'noerror)
|
||||
(doom-initialize-packages))))
|
||||
|
||||
;; Load user config + modules
|
||||
(doom-initialize-modules)
|
||||
;;; Entry point
|
||||
;; HACK: This advice hijacks Emacs' initfile loader to accomplish the following:
|
||||
;;
|
||||
;; 1. Load the profile init file directory (generated on `doom sync`)
|
||||
;; 2. Ignore initfiles we don't care about (like $EMACSDIR/init.el, ~/.emacs,
|
||||
;; and ~/_emacs) -- and spare us the IO of searching for them, and allows
|
||||
;; savvy hackers to use $EMACSDIR as their $DOOMDIR, if they wanted.
|
||||
;; 3. Cut down on unnecessary logic in Emacs' bootstrapper.
|
||||
;; 4. Offer a more user-friendly error state/screen, especially for errors
|
||||
;; emitted from Doom's core or the user's config.
|
||||
(define-advice startup--load-user-init-file (:override (file-fn _ _) init-doom 100)
|
||||
(let ((debug-on-error-from-init-file nil)
|
||||
(debug-on-error-should-be-set nil)
|
||||
(debug-on-error-initial (if (eq init-file-debug t) 'startup init-file-debug)))
|
||||
(let ((debug-on-error debug-on-error-initial))
|
||||
(condition-case-unless-debug error
|
||||
(when init-file-user
|
||||
(let ((init-file-name
|
||||
;; This dynamically generated init file stores a lot of
|
||||
;; precomputed information, such as module and package
|
||||
;; autoloads, and values for expensive variables like
|
||||
;; `doom-modules', `doom-disabled-packages', `load-path',
|
||||
;; `auto-mode-alist', and `Info-directory-list'. etc.
|
||||
;; Compiling them in one place is a big reduction in startup
|
||||
;; time, and by keeping a history of them, you get a snapshot
|
||||
;; of your config in time.
|
||||
(file-name-concat doom-profile-dir (format "init.%d.elc" emacs-major-version))))
|
||||
;; If `user-init-file' is t, then `load' will store the name of
|
||||
;; the file that it loads into `user-init-file'.
|
||||
(setq user-init-file t)
|
||||
(when init-file-name
|
||||
(load init-file-name 'noerror 'nomessage nil 'must-suffix))
|
||||
;; If we did not find the user's init file, set user-init-file
|
||||
;; conclusively. Don't let it be set from default.el.
|
||||
(when (eq user-init-file t)
|
||||
(signal 'doom-nosync-error (list init-file-name))))
|
||||
;; If we loaded a compiled file, set `user-init-file' to the source
|
||||
;; version if that exists.
|
||||
(setq user-init-file
|
||||
(concat (string-remove-suffix (format ".%d.elc" emacs-major-version)
|
||||
user-init-file)
|
||||
".el")))
|
||||
;; TODO: Add safe-mode profile.
|
||||
;; (error
|
||||
;; ;; HACK: This is not really this variable's intended purpose, but it
|
||||
;; ;; doesn't mind what value its set to, only that its non-nil, so I'm
|
||||
;; ;; exploiting its dynamic scope to pass the error to the profile.
|
||||
;; (setq init-file-had-error error)
|
||||
;; (load (file-name-concat doom-emacs-dir "profiles" "safe-mode" "init.el")
|
||||
;; nil 'nomessage 'nosuffix))
|
||||
(error
|
||||
(display-warning
|
||||
'initialization
|
||||
(format-message "\
|
||||
An error occurred while loading `%s':\n\n%s%s%s\n\n\
|
||||
To ensure normal operation, you should investigate and remove the
|
||||
cause of the error in your initialization file. Start Emacs with
|
||||
the `--debug-init' option to view a complete error backtrace."
|
||||
user-init-file
|
||||
(get (car error) 'error-message)
|
||||
(if (cdr error) ": " "")
|
||||
(mapconcat (lambda (s) (prin1-to-string s t))
|
||||
(cdr error) ", "))
|
||||
:warning)
|
||||
(setq init-file-had-error t)))
|
||||
;; If we can tell that the init file altered debug-on-error, arrange to
|
||||
;; preserve the value that it set up.
|
||||
(or (eq debug-on-error debug-on-error-initial)
|
||||
(setq debug-on-error-should-be-set t
|
||||
debug-on-error-from-init-file debug-on-error)))
|
||||
(when debug-on-error-should-be-set
|
||||
(setq debug-on-error debug-on-error-from-init-file))))
|
||||
|
||||
(provide 'doom-start)
|
||||
;;; doom-start.el ends here
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue