Redesign Doom bootstrap, caching & autoload generation logic
The autoloads file has been split into doom-autoload-file and doom-package-autoload-file. The former is for Doom's modules and standard library; the latter is for compiling all package autoloads like load-path and auto-mode-alist (among other things). This reduced my startup speed from ~1s to ~0.5s
This commit is contained in:
parent
3dd291a675
commit
8746c12fae
4 changed files with 413 additions and 259 deletions
|
@ -1,149 +1,255 @@
|
||||||
;;; core/autoload/modules.el -*- lexical-binding: t; -*-
|
;;; core/autoload/modules.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
;;;###autoload
|
(autoload 'print! "autoload/message" nil 'macro)
|
||||||
(defun doom//reload ()
|
(autoload 'printerr! "autoload/message" nil 'macro)
|
||||||
"Reload your private Doom config. Experimental!"
|
|
||||||
(interactive)
|
|
||||||
(when (file-exists-p doom-packages-file)
|
|
||||||
(delete-file doom-packages-file))
|
|
||||||
(cond ((and noninteractive (not (daemonp)))
|
|
||||||
(doom-initialize)
|
|
||||||
(doom//reload-autoloads)
|
|
||||||
(require 'server)
|
|
||||||
(when (server-running-p)
|
|
||||||
(message "Reloading active Emacs session...")
|
|
||||||
(server-eval-at server-name '(doom//reload))))
|
|
||||||
|
|
||||||
((let ((load-prefer-newer t)
|
(defun doom--server-eval (body)
|
||||||
doom-init-p)
|
(require 'server)
|
||||||
(setq doom-modules (make-hash-table :test #'equal :size 100 :rehash-threshold 1.0))
|
(when (server-running-p)
|
||||||
(doom-initialize t)
|
(server-eval-at server-name body)))
|
||||||
(message "%d packages reloaded" (length package-alist))
|
|
||||||
(run-hooks 'doom-reload-hook)))))
|
;;;###autoload
|
||||||
|
(defun doom//reload (&optional force-p)
|
||||||
|
"Reloads your config. This is experimental!
|
||||||
|
|
||||||
|
If called from a noninteractive session, this will try to communicate with a
|
||||||
|
live server (if one is found) to tell it to run this function.
|
||||||
|
|
||||||
|
If called from an interactive session, tries to reload autoloads files (if
|
||||||
|
necessary), reinistalize doom (via `doom-initialize') and reloads your private
|
||||||
|
init.el and config.el. Then runs `doom-reload-hook'."
|
||||||
|
(interactive)
|
||||||
|
(unless doom--inhibit-reload
|
||||||
|
(cond ((and noninteractive (not (daemonp)))
|
||||||
|
(require 'server)
|
||||||
|
(if (not (server-running-p))
|
||||||
|
(doom//reload-autoloads force-p)
|
||||||
|
(print! "Reloading active Emacs session...")
|
||||||
|
(print!
|
||||||
|
(bold "%%s")
|
||||||
|
(if (server-eval-at server-name '(doom//reload))
|
||||||
|
(green "Done!")
|
||||||
|
(red "There were issues!")))))
|
||||||
|
((let ((load-prefer-newer t))
|
||||||
|
(doom//reload-autoloads force-p)
|
||||||
|
(doom-initialize t)
|
||||||
|
(doom-initialize-modules t)
|
||||||
|
(print! (green "%d packages reloaded" (length package-alist)))
|
||||||
|
(run-hooks 'doom-reload-hook))))))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Autoload file generation
|
||||||
|
;;
|
||||||
|
|
||||||
|
(defvar doom-autoload-excluded-packages '(marshal gh)
|
||||||
|
"Packages that have silly or destructive autoload files that try to load
|
||||||
|
everyone in the universe and their dog, causing errors that make babies cry. No
|
||||||
|
one wants that.")
|
||||||
|
|
||||||
|
(defun doom--byte-compile (file)
|
||||||
|
(let ((short-name (file-name-nondirectory file)))
|
||||||
|
(condition-case-unless-debug ex
|
||||||
|
(when (byte-compile-file file)
|
||||||
|
(load (byte-compile-dest-file file) nil t)
|
||||||
|
(unless noninteractive
|
||||||
|
(message "Finished compiling %s" short-name)))
|
||||||
|
('error
|
||||||
|
(doom-delete-autoloads-file file)
|
||||||
|
(error "Error in %s: %s -- %s"
|
||||||
|
short-name
|
||||||
|
(car ex) (error-message-string ex))))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun doom-delete-autoloads-file (file)
|
||||||
|
"Delete FILE (an autoloads file), and delete the accompanying *.elc file, if
|
||||||
|
it exists."
|
||||||
|
(or (stringp file)
|
||||||
|
(signal 'wrong-type-argument (list 'stringp file)))
|
||||||
|
(when (file-exists-p file)
|
||||||
|
(delete-file file)
|
||||||
|
(ignore-errors (delete-file (byte-compile-dest-file file)))
|
||||||
|
(print! "Deleted old %s" (file-name-nondirectory file))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun doom//reload-autoloads (&optional file force-p)
|
||||||
|
"Reloads FILE (an autoload file), if it needs reloading.
|
||||||
|
|
||||||
|
FILE should be one of `doom-autoload-file' or `doom-package-autoload-file'. If
|
||||||
|
it is nil, it will try to reload both. If FORCE-P (universal argument) do it
|
||||||
|
even if it doesn't need reloading!"
|
||||||
|
(interactive
|
||||||
|
(list nil current-prefix-arg))
|
||||||
|
(or (null file)
|
||||||
|
(stringp file)
|
||||||
|
(signal 'wrong-type-argument (list 'stringp file)))
|
||||||
|
(cond ((equal file doom-autoload-file)
|
||||||
|
(doom//reload-doom-autoloads force-p))
|
||||||
|
((equal file doom-package-autoload-file)
|
||||||
|
(doom//reload-package-autoloads force-p))
|
||||||
|
((progn
|
||||||
|
(doom//reload-doom-autoloads force-p)
|
||||||
|
(doom//reload-package-autoloads force-p)))))
|
||||||
|
|
||||||
(defvar generated-autoload-load-name)
|
(defvar generated-autoload-load-name)
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom//reload-autoloads (&optional force)
|
(defun doom//reload-doom-autoloads (&optional force-p)
|
||||||
"Refreshes the autoloads.el file, specified by `doom-autoload-file'.
|
"Refreshes the autoloads.el file, specified by `doom-autoload-file', if
|
||||||
|
necessary (or if FORCE-P is non-nil).
|
||||||
|
|
||||||
It scans and reads core/autoload/*.el, modules/*/*/autoload.el and
|
It scans and reads core/autoload/*.el, modules/*/*/autoload.el and
|
||||||
modules/*/*/autoload/*.el, and generates an autoloads file at the path specified
|
modules/*/*/autoload/*.el, and generates `doom-autoload-file'. This file tells
|
||||||
by `doom-autoload-file'. This file tells Emacs where to find lazy-loaded
|
Emacs where to find lazy-loaded functions.
|
||||||
functions.
|
|
||||||
|
|
||||||
This should be run whenever init.el or an autoload file is modified. Running
|
This should be run whenever your `doom!' block, or a module autoload file, is
|
||||||
'make autoloads' from the commandline executes this command."
|
modified."
|
||||||
(interactive)
|
(interactive)
|
||||||
;; This function must not use autoloaded functions or external dependencies.
|
(let ((doom-modules (doom-module-table))
|
||||||
;; It must assume nothing is set up!
|
(default-directory doom-emacs-dir)
|
||||||
(let ((default-directory doom-emacs-dir)
|
|
||||||
(targets
|
(targets
|
||||||
(file-expand-wildcards
|
(file-expand-wildcards
|
||||||
(expand-file-name "autoload/*.el" doom-core-dir)))
|
(expand-file-name "autoload/*.el" doom-core-dir))))
|
||||||
(generate-autoload-section-continuation "")
|
|
||||||
(generate-autoload-section-header "")
|
|
||||||
(generate-autoload-section-trailer "")
|
|
||||||
(doom--stage 'autoloads)
|
|
||||||
outdated)
|
|
||||||
(dolist (path (doom-module-load-path))
|
(dolist (path (doom-module-load-path))
|
||||||
(let ((auto-dir (expand-file-name "autoload" path))
|
(let ((auto-dir (expand-file-name "autoload" path))
|
||||||
(auto-file (expand-file-name "autoload.el" path)))
|
(auto-file (expand-file-name "autoload.el" path)))
|
||||||
(when (file-exists-p auto-file)
|
(when (file-exists-p auto-file)
|
||||||
(push auto-file targets))
|
(push auto-file targets))
|
||||||
(when (file-directory-p auto-dir)
|
(when (file-directory-p auto-dir)
|
||||||
(dolist (file (doom-files-under auto-dir :match "\\.el$"))
|
(dolist (file (doom-files-in auto-dir :match "\\.el$" :full t))
|
||||||
(push file targets)))))
|
(push file targets)))))
|
||||||
(when (file-exists-p doom-autoload-file)
|
(if (and (not force-p)
|
||||||
(delete-file doom-autoload-file)
|
(file-exists-p doom-autoload-file)
|
||||||
(ignore-errors (delete-file (byte-compile-dest-file doom-autoload-file)))
|
(not (cl-loop for file in targets
|
||||||
(message "Deleted old autoloads.el"))
|
if (file-newer-than-file-p file doom-autoload-file)
|
||||||
(message "Generating new autoloads.el")
|
return t)))
|
||||||
(dolist (file (mapcar #'file-truename (reverse targets)))
|
(ignore (print! (green "Doom core autoloads is up-to-date"))
|
||||||
(let ((generated-autoload-load-name (file-name-sans-extension file)))
|
(doom-initialize-autoloads doom-autoload-file))
|
||||||
(message
|
(doom-delete-autoloads-file doom-autoload-file)
|
||||||
(cond ((not (doom-file-cookie-p file))
|
;; in case the buffer is open somewhere and modified
|
||||||
"⚠ Ignoring %s")
|
(when-let* ((buf (find-buffer-visiting doom-autoload-file)))
|
||||||
((update-file-autoloads file nil doom-autoload-file)
|
(with-current-buffer buf
|
||||||
"✕ Nothing in %s")
|
(set-buffer-modified-p nil))
|
||||||
("✓ Scanned %s"))
|
(kill-buffer buf))
|
||||||
(if (file-in-directory-p file default-directory)
|
(message "Generating new autoloads.el")
|
||||||
(file-relative-name file)
|
(dolist (file (nreverse targets))
|
||||||
(abbreviate-file-name file)))))
|
(let* ((file (file-truename file))
|
||||||
(make-directory (file-name-directory doom-autoload-file) t)
|
(generated-autoload-load-name (file-name-sans-extension file))
|
||||||
(let ((buf (find-file-noselect doom-autoload-file t))
|
(noninteractive (not doom-debug-mode)))
|
||||||
(load-path (append doom-psuedo-module-dirs
|
(print!
|
||||||
doom-modules-dirs
|
(cond ((not (doom-file-cookie-p file))
|
||||||
load-path))
|
"⚠ Ignoring %s")
|
||||||
case-fold-search)
|
((update-file-autoloads file nil doom-autoload-file)
|
||||||
;; FIXME Make me faster
|
(yellow "✕ Nothing in %%s"))
|
||||||
(unwind-protect
|
((green "✓ Scanned %%s")))
|
||||||
(with-current-buffer buf
|
(if (file-in-directory-p file default-directory)
|
||||||
(goto-char (point-min))
|
(file-relative-name file)
|
||||||
(insert ";;; -*- lexical-binding:t -*-\n"
|
(abbreviate-file-name file)))))
|
||||||
";; This file is autogenerated by `doom//reload-autoloads', DO NOT EDIT !!\n\n")
|
(make-directory (file-name-directory doom-autoload-file) t)
|
||||||
|
(let ((buf (find-file-noselect doom-autoload-file t))
|
||||||
|
case-fold-search)
|
||||||
|
(unwind-protect
|
||||||
|
(with-current-buffer buf
|
||||||
|
(goto-char (point-min))
|
||||||
|
(insert ";;; -*- lexical-binding:t -*-\n"
|
||||||
|
";; This file is autogenerated by `doom//reload-doom-autoloads', DO NOT EDIT !!\n\n")
|
||||||
|
(save-excursion
|
||||||
|
;; Replace autoload paths (only for module autoloads) with
|
||||||
|
;; absolute paths for faster resolution during load and
|
||||||
|
;; simpler `load-path'
|
||||||
|
(let ((load-path (append doom-psuedo-module-dirs
|
||||||
|
doom-modules-dirs
|
||||||
|
load-path))
|
||||||
|
cache)
|
||||||
|
(save-excursion
|
||||||
|
(while (re-search-forward "^\\s-*(autoload\\s-+'[^ ]+\\s-+\"\\([^\"]*\\)\"" nil t)
|
||||||
|
(let ((path (match-string 1)))
|
||||||
|
(replace-match
|
||||||
|
(or (cdr (assoc path cache))
|
||||||
|
(when-let* ((libpath (locate-library path))
|
||||||
|
(libpath (file-name-sans-extension libpath)))
|
||||||
|
(push (cons path (abbreviate-file-name libpath)) cache)
|
||||||
|
libpath)
|
||||||
|
path)
|
||||||
|
t t nil 1)))
|
||||||
|
(print! (green "✓ Autoload paths expanded")))))
|
||||||
|
;; Remove byte-compile inhibiting file variables so we can
|
||||||
|
;; byte-compile the file.
|
||||||
|
(when (re-search-forward "^;; no-byte-compile: t\n" nil t)
|
||||||
|
(replace-match "" t t))
|
||||||
|
;; Byte compile it to give the file a chance to reveal errors.
|
||||||
|
(save-buffer)
|
||||||
|
(doom--byte-compile doom-autoload-file)
|
||||||
|
(when (and noninteractive (not (daemonp)))
|
||||||
|
(doom--server-eval `(load-file ,doom-autoload-file)))
|
||||||
|
t)
|
||||||
|
(kill-buffer buf))))))
|
||||||
|
|
||||||
;; Replace autoload paths (only for module autoloads) with
|
;;;###autoload
|
||||||
;; absolute paths for faster resolution during load and simpler
|
(defun doom//reload-package-autoloads (&optional force-p)
|
||||||
;; `load-path'
|
"Compiles `doom-package-autoload-file' from the autoloads files of all
|
||||||
(save-excursion
|
installed packages. It also caches `load-path', `Info-directory-list',
|
||||||
(let (cache)
|
`doom-disabled-packages', `package-activated-list' and `auto-mode-alist'.
|
||||||
(while (re-search-forward "^\\s-*(autoload\\s-+'[^ ]+\\s-+\"\\([^\"]*\\)\"" nil t)
|
|
||||||
(let ((path (match-string 1)))
|
|
||||||
(replace-match
|
|
||||||
(or (cdr (assoc path cache))
|
|
||||||
(when-let* ((libpath (locate-library path))
|
|
||||||
(libpath (file-name-sans-extension libpath)))
|
|
||||||
(push (cons path (abbreviate-file-name libpath)) cache)
|
|
||||||
libpath)
|
|
||||||
(progn
|
|
||||||
(warn "Couldn't find absolute path for: %s" path)
|
|
||||||
path))
|
|
||||||
t t nil 1))))
|
|
||||||
(message "✓ Autoload paths expanded"))
|
|
||||||
|
|
||||||
;; insert package autoloads
|
Will do nothing if none of your installed packages have been modified. If
|
||||||
(save-excursion
|
FORCE-P (universal argument) is non-nil, regenerate it anyway.
|
||||||
(dolist (spec package-alist)
|
|
||||||
(let ((pkg (car spec)))
|
|
||||||
(unless (memq pkg doom-autoload-excluded-packages)
|
|
||||||
(let ((file
|
|
||||||
(abbreviate-file-name
|
|
||||||
(concat (package--autoloads-file-name (cadr spec)) ".el"))))
|
|
||||||
(insert "(let ((load-file-name " (prin1-to-string file) "))\n")
|
|
||||||
(insert-file-contents file)
|
|
||||||
(while (re-search-forward "^\\(?:;;\\(.*\n\\)\\|\n\\)" nil t)
|
|
||||||
(unless (nth 8 (syntax-ppss))
|
|
||||||
(replace-match "" t t)))
|
|
||||||
(unless (bolp) (insert "\n"))
|
|
||||||
(insert ")\n")))))
|
|
||||||
(message "✓ Package autoloads included"))
|
|
||||||
|
|
||||||
;; Remove `load-path' and `auto-mode-alist' modifications (most
|
This should be run whenever your `doom!' block or update your packages."
|
||||||
;; of them, at least); they are cached elsewhere, so these are
|
(interactive)
|
||||||
;; unnecessary overhead.
|
(if (and (not force-p)
|
||||||
(while (re-search-forward (concat "^\\s-*(\\(add-to-list\\s-+'\\(?:load-path\\|auto-mode-alist\\)\\)")
|
(file-exists-p doom-package-autoload-file)
|
||||||
nil t)
|
(not (cl-loop initially do (doom-ensure-packages-initialized t)
|
||||||
(beginning-of-line)
|
for (_pkg desc) in package-alist
|
||||||
(skip-chars-forward " \t")
|
for autoload-file = (concat (package--autoloads-file-name desc) ".el")
|
||||||
(kill-sexp))
|
if (file-newer-than-file-p autoload-file doom-package-autoload-file)
|
||||||
(message "✓ load-path/auto-mode-alist entries removed")
|
return t)))
|
||||||
|
(ignore (print! (green "Doom package autoloads is up-to-date"))
|
||||||
|
(doom-initialize-autoloads doom-package-autoload-file))
|
||||||
|
(doom-delete-autoloads-file doom-package-autoload-file)
|
||||||
|
(with-temp-file doom-package-autoload-file
|
||||||
|
(insert ";;; -*- lexical-binding:t -*-\n"
|
||||||
|
";; This file is autogenerated by `doom//reload-package-autoloads', DO NOT EDIT !!\n\n")
|
||||||
|
;; insert package autoloads
|
||||||
|
(save-excursion
|
||||||
|
(dolist (spec package-alist)
|
||||||
|
(cl-destructuring-bind (pkg desc) spec
|
||||||
|
(unless (memq pkg doom-autoload-excluded-packages)
|
||||||
|
(let ((file
|
||||||
|
(abbreviate-file-name
|
||||||
|
(concat (package--autoloads-file-name desc) ".el"))))
|
||||||
|
(when (file-exists-p file)
|
||||||
|
(insert "(let ((load-file-name " (prin1-to-string file) "))\n")
|
||||||
|
(insert-file-contents file)
|
||||||
|
(while (re-search-forward "^\\(?:;;\\(.*\n\\)\\|\n\\)" nil t)
|
||||||
|
(unless (nth 8 (syntax-ppss))
|
||||||
|
(replace-match "" t t)))
|
||||||
|
(unless (bolp) (insert "\n"))
|
||||||
|
(insert ")\n"))))))
|
||||||
|
(print! (green "✓ Package autoloads included"))
|
||||||
|
;; Cache the important and expensive-to-initialize state here.
|
||||||
|
(doom-initialize-packages 'internal)
|
||||||
|
(prin1 `(setq load-path ',load-path
|
||||||
|
auto-mode-alist ',auto-mode-alist
|
||||||
|
Info-directory-list ',Info-directory-list
|
||||||
|
doom-disabled-packages ',doom-disabled-packages
|
||||||
|
package-activated-list ',package-activated-list)
|
||||||
|
(current-buffer))
|
||||||
|
(print! (green "✓ Cached package state")))
|
||||||
|
;; Remove `load-path' and `auto-mode-alist' modifications (most of them,
|
||||||
|
;; at least); they are cached later, so all those membership checks are
|
||||||
|
;; unnecessary overhead.
|
||||||
|
(while (re-search-forward "^\\s-*\\((\\(?:add-to-list\\|when (boundp \\)\\s-+'\\(?:load-path\\|auto-mode-alist\\)\\)" nil t)
|
||||||
|
(goto-char (match-beginning 1))
|
||||||
|
(kill-sexp))
|
||||||
|
(print! (green "✓ Removed load-path/auto-mode-alist entries")))
|
||||||
|
(doom--byte-compile doom-package-autoload-file)
|
||||||
|
(when (and noninteractive (not (daemonp)))
|
||||||
|
(doom--server-eval `(load-file ,doom-package-autoload-file)))
|
||||||
|
t))
|
||||||
|
|
||||||
;; Remove byte-compile inhibiting file variables so we can
|
|
||||||
;; byte-compile the file.
|
|
||||||
(when (re-search-forward "^;; no-byte-compile: t\n$" nil t)
|
|
||||||
(replace-match "" t t))
|
|
||||||
(save-buffer)
|
|
||||||
|
|
||||||
;; Byte compile it to give the file a chance to reveal errors.
|
;;
|
||||||
(condition-case-unless-debug ex
|
;; Byte compilation
|
||||||
(quiet! (byte-compile-file doom-autoload-file 'load))
|
;;
|
||||||
('error
|
|
||||||
(delete-file doom-autoload-file)
|
|
||||||
(message "Deleting autoloads file!")
|
|
||||||
(error "Error in autoloads.el: %s -- %s"
|
|
||||||
(car ex) (error-message-string ex))))
|
|
||||||
(message "Done!"))
|
|
||||||
(kill-buffer buf)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom//byte-compile (&optional modules recompile-p)
|
(defun doom//byte-compile (&optional modules recompile-p)
|
||||||
|
|
|
@ -40,53 +40,47 @@
|
||||||
;; See core/autoload/packages.el for more functions.
|
;; See core/autoload/packages.el for more functions.
|
||||||
|
|
||||||
(defvar doom-init-p nil
|
(defvar doom-init-p nil
|
||||||
"Non-nil if doom is done initializing (once `doom-post-init-hook' is done). If
|
"Non-nil if `doom-initialize' has run.")
|
||||||
this is nil after Emacs has started something is wrong.")
|
|
||||||
|
(defvar doom-init-modules-p nil
|
||||||
|
"Non-nil if `doom-initialize-modules' has run.")
|
||||||
|
|
||||||
(defvar doom-init-time nil
|
(defvar doom-init-time nil
|
||||||
"The time it took, in seconds, for DOOM Emacs to initialize.")
|
"The time it took, in seconds, for DOOM Emacs to initialize.")
|
||||||
|
|
||||||
(defvar doom-modules
|
(defvar doom-modules ()
|
||||||
(make-hash-table :test #'equal :size 100 :rehash-threshold 1.0)
|
|
||||||
"A hash table of enabled modules. Set by `doom-initialize-modules'.")
|
"A hash table of enabled modules. Set by `doom-initialize-modules'.")
|
||||||
|
|
||||||
(defvar doom-modules-dirs
|
(defvar doom-modules-dirs
|
||||||
(list (expand-file-name "modules/" doom-private-dir) doom-modules-dir)
|
(list (expand-file-name "modules/" doom-private-dir) doom-modules-dir)
|
||||||
"A list of module root directories. Order determines priority.")
|
"A list of module root directories. Order determines priority.")
|
||||||
|
|
||||||
(defvar doom-psuedo-module-dirs
|
(defvar doom-psuedo-module-dirs (list doom-private-dir)
|
||||||
(list doom-private-dir)
|
|
||||||
"Additional paths for modules that are outside of `doom-modules-dirs'.
|
"Additional paths for modules that are outside of `doom-modules-dirs'.
|
||||||
`doom//reload-autoloads', `doom//byte-compile' and `doom-initialize-packages'
|
`doom//reload-doom-autoloads', `doom//byte-compile' and
|
||||||
will include the directories in this list.")
|
`doom-initialize-packages' will include the directories in this list.")
|
||||||
|
|
||||||
(defvar doom-packages ()
|
(defvar doom-packages ()
|
||||||
"A list of enabled packages. Each element is a sublist, whose CAR is the
|
"A list of enabled packages. Each element is a sublist, whose CAR is the
|
||||||
package's name as a symbol, and whose CDR is the plist supplied to its
|
package's name as a symbol, and whose CDR is the plist supplied to its
|
||||||
`package!' declaration. Set by `doom-initialize-packages'.")
|
`package!' declaration. Set by `doom-initialize-packages'.")
|
||||||
|
|
||||||
(defvar doom-core-packages
|
(defvar doom-core-packages '(persistent-soft use-package quelpa async)
|
||||||
'(persistent-soft use-package quelpa async)
|
|
||||||
"A list of packages that must be installed (and will be auto-installed if
|
"A list of packages that must be installed (and will be auto-installed if
|
||||||
missing) and shouldn't be deleted.")
|
missing) and shouldn't be deleted.")
|
||||||
|
|
||||||
(defvar doom-disabled-packages ()
|
(defvar doom-disabled-packages ()
|
||||||
"A list of packages that should be ignored by `def-package!'.")
|
"A list of packages that should be ignored by `def-package!'.")
|
||||||
|
|
||||||
(defvar doom-autoload-excluded-packages '(marshal gh)
|
|
||||||
"Packages that have silly or destructive autoload files that try to load
|
|
||||||
everyone in the universe and their dog, causing errors that make babies cry. No
|
|
||||||
one wants that.")
|
|
||||||
|
|
||||||
(defvar doom-site-load-path load-path
|
(defvar doom-site-load-path load-path
|
||||||
"The starting load-path, before it is altered by `doom-initialize'.")
|
"The starting load-path, before it is altered by `doom-initialize'.")
|
||||||
|
|
||||||
(defvar doom-autoload-file (concat doom-local-dir "autoloads.el")
|
(defvar doom-autoload-file (concat doom-local-dir "autoloads.el")
|
||||||
"Where `doom//reload-autoloads' will generate its autoloads file.")
|
"Where `doom//reload-doom-autoloads' will generate its core autoloads file.")
|
||||||
|
|
||||||
(defvar doom-packages-file (concat doom-cache-dir "packages.el")
|
(defvar doom-package-autoload-file (concat doom-local-dir "autoloads.pkg.el")
|
||||||
"Where to cache `load-path', `Info-directory-list', `doom-disabled-packages'
|
"Where `doom//reload-package-autoloads' will generate its package.el autoloads
|
||||||
and `auto-mode-alist'.")
|
file.")
|
||||||
|
|
||||||
(defvar doom-reload-hook nil
|
(defvar doom-reload-hook nil
|
||||||
"A list of hooks to run when `doom//reload-load-path' is called.")
|
"A list of hooks to run when `doom//reload-load-path' is called.")
|
||||||
|
@ -150,22 +144,6 @@ and `auto-mode-alist'.")
|
||||||
(file-relative-name load-file-name doom-emacs-dir)
|
(file-relative-name load-file-name doom-emacs-dir)
|
||||||
(abbreviate-file-name load-file-name))))
|
(abbreviate-file-name load-file-name))))
|
||||||
|
|
||||||
(defun doom|refresh-cache ()
|
|
||||||
"Refresh `doom-packages-file', which caches `load-path',
|
|
||||||
`Info-directory-list', `doom-disabled-packages', `auto-mode-alist' and
|
|
||||||
`package-activated-list'."
|
|
||||||
(doom-initialize-packages 'internal)
|
|
||||||
(let ((coding-system-for-write 'emacs-internal))
|
|
||||||
(with-temp-file doom-packages-file
|
|
||||||
(insert ";;; -*- lexical-binding:t -*-\n"
|
|
||||||
";; This file was autogenerated by `doom|refresh-cache', DO NOT EDIT!\n")
|
|
||||||
(prin1 `(setq load-path ',load-path
|
|
||||||
auto-mode-alist ',auto-mode-alist
|
|
||||||
Info-directory-list ',Info-directory-list
|
|
||||||
doom-disabled-packages ',doom-disabled-packages
|
|
||||||
package-activated-list ',package-activated-list)
|
|
||||||
(current-buffer)))))
|
|
||||||
|
|
||||||
(defun doom|display-benchmark (&optional return-p)
|
(defun doom|display-benchmark (&optional return-p)
|
||||||
"Display a benchmark, showing number of packages and modules, and how quickly
|
"Display a benchmark, showing number of packages and modules, and how quickly
|
||||||
they were loaded at startup.
|
they were loaded at startup.
|
||||||
|
@ -195,17 +173,59 @@ session, with a different init.el, like so:
|
||||||
'window-setup-hook))
|
'window-setup-hook))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Bootstrap helpers
|
||||||
|
;;
|
||||||
|
|
||||||
|
(defun doom-ensure-packages-initialized (&optional force-p)
|
||||||
|
"Make sure package.el is initialized."
|
||||||
|
(when (or force-p (not package--initialized))
|
||||||
|
(require 'package)
|
||||||
|
(setq package-activated-list nil
|
||||||
|
package--initialized nil)
|
||||||
|
(let (byte-compile-warnings)
|
||||||
|
(condition-case _
|
||||||
|
(quiet! (package-initialize))
|
||||||
|
('error (package-refresh-contents)
|
||||||
|
(setq doom--refreshed-p t)
|
||||||
|
(package-initialize))))))
|
||||||
|
|
||||||
|
(defun doom-ensure-core-packages ()
|
||||||
|
"Make sure `doom-core-packages' are installed."
|
||||||
|
(when-let* ((core-packages (cl-remove-if #'package-installed-p doom-core-packages)))
|
||||||
|
(message "Installing core packages")
|
||||||
|
(unless doom--refreshed-p
|
||||||
|
(package-refresh-contents))
|
||||||
|
(dolist (package core-packages)
|
||||||
|
(let ((inhibit-message t))
|
||||||
|
(package-install package))
|
||||||
|
(if (package-installed-p package)
|
||||||
|
(message "✓ Installed %s" package)
|
||||||
|
(error "✕ Couldn't install %s" package)))
|
||||||
|
(message "Installing core packages...done")))
|
||||||
|
|
||||||
|
(defun doom-ensure-core-directories ()
|
||||||
|
"Make sure all Doom's essential local directories (in and including
|
||||||
|
`doom-local-dir') exist."
|
||||||
|
(dolist (dir (list doom-local-dir doom-etc-dir doom-cache-dir doom-packages-dir))
|
||||||
|
(unless (file-directory-p dir)
|
||||||
|
(make-directory dir t))))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Bootstrap API
|
;; Bootstrap API
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
(autoload 'doom//reload-doom-autoloads "autoload/modules" nil t)
|
||||||
|
(autoload 'doom//reload-package-autoloads "autoload/modules" nil t)
|
||||||
|
|
||||||
(defun doom-initialize (&optional force-p)
|
(defun doom-initialize (&optional force-p)
|
||||||
"Bootstrap Doom, if it hasn't already (or if FORCE-P is non-nil).
|
"Bootstrap Doom, if it hasn't already (or if FORCE-P is non-nil).
|
||||||
|
|
||||||
The bootstrap process involves making sure the essential directories exist, core
|
The bootstrap process involves making sure 1) the essential directories exist,
|
||||||
packages are installed, `doom-autoload-file' is loaded, `doom-packages-file'
|
2) the core packages are installed, 3) `doom-autoload-file' and
|
||||||
cache exists (and is loaded) and, finally, loads your private init.el (which
|
`doom-package-autoload-file' exist and have been loaded, and 4) Doom's core
|
||||||
should contain your `doom!' block).
|
files are loaded.
|
||||||
|
|
||||||
If the cache exists, much of this function isn't run, which substantially
|
If the cache exists, much of this function isn't run, which substantially
|
||||||
reduces startup time.
|
reduces startup time.
|
||||||
|
@ -228,71 +248,54 @@ Module load order is determined by your `doom!' block. See `doom-modules-dirs'
|
||||||
for a list of all recognized module trees. Order defines precedence (from most
|
for a list of all recognized module trees. Order defines precedence (from most
|
||||||
to least)."
|
to least)."
|
||||||
(when (or force-p (not doom-init-p))
|
(when (or force-p (not doom-init-p))
|
||||||
(when (and (or force-p noninteractive)
|
;; Set this to prevent infinite recursive calls to `doom-initialize'
|
||||||
(file-exists-p doom-packages-file))
|
(setq doom-init-p t)
|
||||||
(message "Deleting packages.el cache")
|
;; `doom-autoload-file' tells Emacs where to load all its autoloaded
|
||||||
(delete-file doom-packages-file))
|
;; functions from. This includes everything in core/autoload/*.el and all
|
||||||
(unless (load doom-packages-file 'noerror 'nomessage 'nosuffix)
|
;; the autoload files in your enabled modules.
|
||||||
;; Ensure core folders exist, otherwise we get errors
|
(unless (doom-initialize-autoloads doom-autoload-file force-p)
|
||||||
(dolist (dir (list doom-local-dir doom-etc-dir doom-cache-dir doom-packages-dir))
|
(doom-ensure-core-directories)
|
||||||
(unless (file-directory-p dir)
|
(doom-ensure-packages-initialized force-p)
|
||||||
(make-directory dir t)))
|
(doom-ensure-core-packages)
|
||||||
;; Ensure plugins have been initialized
|
;; Regenerate `doom-autoload-file', which tells Doom where to find all its
|
||||||
(require 'package)
|
;; module autoloaded functions.
|
||||||
(setq package-activated-list nil
|
(unless (or force-p noninteractive)
|
||||||
package--initialized nil)
|
(doom//reload-doom-autoloads)))
|
||||||
(let (byte-compile-warnings)
|
;; Loads `doom-package-autoload-file', which caches `load-path',
|
||||||
(condition-case _
|
;; `auto-mode-alist', `Info-directory-list', `doom-disabled-packages' and
|
||||||
(package-initialize)
|
;; `package-activated-list'. A big reduction in startup time.
|
||||||
('error (package-refresh-contents)
|
(unless (doom-initialize-autoloads doom-package-autoload-file force-p)
|
||||||
(setq doom--refreshed-p t)
|
(unless (or force-p noninteractive)
|
||||||
(package-initialize))))
|
(doom//reload-package-autoloads))))
|
||||||
;; Ensure core packages are installed
|
|
||||||
(when-let* ((core-packages (cl-remove-if #'package-installed-p doom-core-packages)))
|
|
||||||
(message "Installing core packages")
|
|
||||||
(unless doom--refreshed-p
|
|
||||||
(package-refresh-contents))
|
|
||||||
(dolist (package core-packages)
|
|
||||||
(let ((inhibit-message t))
|
|
||||||
(package-install package))
|
|
||||||
(if (package-installed-p package)
|
|
||||||
(message "✓ Installed %s" package)
|
|
||||||
(error "✕ Couldn't install %s" package)))
|
|
||||||
(message "Installing core packages...done"))
|
|
||||||
(unless noninteractive
|
|
||||||
(add-hook 'doom-pre-init-hook #'doom|refresh-cache)))
|
|
||||||
;; Load autoloads file
|
|
||||||
(doom-initialize-autoloads))
|
|
||||||
;; Initialize Doom core
|
;; Initialize Doom core
|
||||||
(unless noninteractive
|
(unless noninteractive
|
||||||
(require 'core-ui)
|
(require 'core-ui)
|
||||||
(require 'core-editor)
|
(require 'core-editor)
|
||||||
(require 'core-projects)
|
(require 'core-projects)
|
||||||
(require 'core-keybinds))
|
(require 'core-keybinds)))
|
||||||
;; Bootstrap Doom
|
|
||||||
(unless doom-init-p
|
(defun doom-initialize-modules (&optional force-p)
|
||||||
|
"Loads the init.el in `doom-private-dir' and sets up hooks for a healthy
|
||||||
|
session of Dooming. Will noop if used more than once, unless FORCE-P is
|
||||||
|
non-nil."
|
||||||
|
(when (or force-p (not doom-init-modules-p))
|
||||||
|
;; Set `doom-init-modules-p' early, so `doom-pre-init-hook' won't infinitely
|
||||||
|
;; recurse by accident if any of them need `doom-initialize-modules'.
|
||||||
|
(setq doom-init-modules-p t)
|
||||||
(unless noninteractive
|
(unless noninteractive
|
||||||
(add-hook! 'doom-reload-hook
|
|
||||||
#'(doom|refresh-cache doom|display-benchmark))
|
|
||||||
(add-hook! 'emacs-startup-hook
|
(add-hook! 'emacs-startup-hook
|
||||||
#'(doom|post-init doom|display-benchmark)))
|
#'(doom|post-init doom|display-benchmark)))
|
||||||
(run-hooks 'doom-pre-init-hook)
|
(run-hooks 'doom-pre-init-hook)
|
||||||
(when doom-private-dir
|
(when doom-private-dir
|
||||||
(load (concat doom-private-dir "init") t t)))
|
(let ((load-prefer-newer t))
|
||||||
(setq doom-init-p t))
|
(load (expand-file-name "init" doom-private-dir)
|
||||||
|
'noerror 'nomessage)))))
|
||||||
|
|
||||||
(defun doom-initialize-autoloads ()
|
(defun doom-initialize-autoloads (file &optional clear-p)
|
||||||
"Tries to load `doom-autoload-file', otherwise throws an error (unless in a
|
"Tries to load FILE (an autoloads file). Otherwise tries to regenerate it. If
|
||||||
noninteractive session)."
|
CLEAR-P is non-nil, regenerate it anyway."
|
||||||
(unless
|
(unless clear-p
|
||||||
(condition-case-unless-debug e
|
(load (file-name-sans-extension file) 'noerror 'nomessage)))
|
||||||
(load (substring doom-autoload-file 0 -3) 'noerror 'nomessage)
|
|
||||||
(error
|
|
||||||
(funcall (if noninteractive #'warn #'error)
|
|
||||||
"Autoload error: %s -> %s"
|
|
||||||
(car e) (error-message-string e))))
|
|
||||||
(unless noninteractive
|
|
||||||
(error "No autoloads file! Run make autoloads"))))
|
|
||||||
|
|
||||||
(defun doom-initialize-packages (&optional force-p)
|
(defun doom-initialize-packages (&optional force-p)
|
||||||
"Ensures that Doom's package management system, package.el and quelpa are
|
"Ensures that Doom's package management system, package.el and quelpa are
|
||||||
|
@ -306,8 +309,8 @@ Use this before any of package.el, quelpa or Doom's package management's API to
|
||||||
ensure all the necessary package metadata is initialized and available for
|
ensure all the necessary package metadata is initialized and available for
|
||||||
them."
|
them."
|
||||||
(with-temp-buffer ; prevent buffer-local settings from propagating
|
(with-temp-buffer ; prevent buffer-local settings from propagating
|
||||||
;; Prefer uncompiled files to reduce stale code issues
|
(let ((load-prefer-newer t) ; reduce stale code issues
|
||||||
(let ((load-prefer-newer t))
|
(doom-modules (doom-module-table)))
|
||||||
;; package.el and quelpa handle themselves if their state changes during
|
;; package.el and quelpa handle themselves if their state changes during
|
||||||
;; the current session, but if you change an packages.el file in a module,
|
;; the current session, but if you change an packages.el file in a module,
|
||||||
;; there's no non-trivial way to detect that, so we give you a way to
|
;; there's no non-trivial way to detect that, so we give you a way to
|
||||||
|
@ -454,6 +457,37 @@ added, if the file exists."
|
||||||
collect (plist-get plist :path))
|
collect (plist-get plist :path))
|
||||||
(cl-remove-if-not #'file-directory-p doom-psuedo-module-dirs)))
|
(cl-remove-if-not #'file-directory-p doom-psuedo-module-dirs)))
|
||||||
|
|
||||||
|
(defun doom-module-table (&optional modules)
|
||||||
|
"Converts MODULES (a malformed plist) into a hash table of modules, fit for
|
||||||
|
`doom-modules'. If MODULES is omitted, it will fetch your module mplist from the
|
||||||
|
`doom!' block in your private init.el file."
|
||||||
|
(let* ((doom-modules (make-hash-table :test #'equal
|
||||||
|
:size (if modules (length modules) 100)
|
||||||
|
:rehash-threshold 1.0)))
|
||||||
|
(when (null modules)
|
||||||
|
(let ((init-file (expand-file-name "init.el" doom-private-dir)))
|
||||||
|
(if (not (file-exists-p init-file))
|
||||||
|
(error "%s doesn't exist" (abbreviate-file-name init-file))
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert-file-contents init-file)
|
||||||
|
(when (re-search-forward "^\\s-*\\((doom! \\)" nil t)
|
||||||
|
(goto-char (match-beginning 1))
|
||||||
|
(setq modules (cdr (sexp-at-point))))))
|
||||||
|
(unless modules
|
||||||
|
(error "Couldn't gather module list from %s" init-file))))
|
||||||
|
(if (eq modules t) (setq modules nil))
|
||||||
|
(let (category)
|
||||||
|
(dolist (m modules)
|
||||||
|
(cond ((keywordp m) (setq category m))
|
||||||
|
((not category) (error "No module category specified for %s" m))
|
||||||
|
((let ((module (if (listp m) (car m) m))
|
||||||
|
(flags (if (listp m) (cdr m))))
|
||||||
|
(if-let* ((path (doom-module-locate-path category module)))
|
||||||
|
(doom-module-set category module :flags flags :path path)
|
||||||
|
(when doom-debug-mode
|
||||||
|
(message "Couldn't find the %s %s module" category module))))))))
|
||||||
|
doom-modules))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Use-package modifications
|
;; Use-package modifications
|
||||||
|
@ -506,25 +540,40 @@ added, if the file exists."
|
||||||
(defmacro doom! (&rest modules)
|
(defmacro doom! (&rest modules)
|
||||||
"Bootstraps DOOM Emacs and its modules.
|
"Bootstraps DOOM Emacs and its modules.
|
||||||
|
|
||||||
MODULES is an malformed plist of modules to load."
|
The bootstrap process involves making sure the essential directories exist, core
|
||||||
(let (init-forms config-forms file-name-handler-alist)
|
packages are installed, `doom-autoload-file' is loaded, `doom-packages-file'
|
||||||
(let (module)
|
cache exists (and is loaded) and, finally, loads your private init.el (which
|
||||||
(dolist (m modules)
|
should contain your `doom!' block).
|
||||||
(cond ((keywordp m) (setq module m))
|
|
||||||
((not module) (error "No namespace specified in `doom!' for %s" m))
|
If the cache exists, much of this function isn't run, which substantially
|
||||||
((let ((submodule (if (listp m) (car m) m))
|
reduces startup time.
|
||||||
(flags (if (listp m) (cdr m))))
|
|
||||||
(let ((path (doom-module-locate-path module submodule)))
|
The overall load order of Doom is as follows:
|
||||||
(if (not path)
|
|
||||||
(when doom-debug-mode
|
~/.emacs.d/init.el
|
||||||
(message "Couldn't find the %s %s module" module submodule))
|
~/.emacs.d/core/core.el
|
||||||
(doom-module-set module submodule :flags flags :path path)
|
`doom-pre-init-hook'
|
||||||
(push `(let ((doom--current-module ',(cons module submodule)))
|
~/.doom.d/init.el
|
||||||
(load! init ,path t))
|
Module init.el files
|
||||||
init-forms)
|
`doom-init-hook'
|
||||||
(push `(let ((doom--current-module ',(cons module submodule)))
|
Module config.el files
|
||||||
(load! config ,path t))
|
~/.doom.d/config.el
|
||||||
config-forms))))))))
|
`after-init-hook'
|
||||||
|
`emacs-startup-hook'
|
||||||
|
`doom-post-init-hook' (at end of `emacs-startup-hook')
|
||||||
|
|
||||||
|
Module load order is determined by your `doom!' block. See `doom-modules-dirs'
|
||||||
|
for a list of all recognized module trees. Order defines precedence (from most
|
||||||
|
to least)."
|
||||||
|
(let ((doom-modules (doom-module-table (or modules t)))
|
||||||
|
init-forms config-forms file-name-handler-alist)
|
||||||
|
(maphash (lambda (key value)
|
||||||
|
(let ((path (plist-get value :path)))
|
||||||
|
(push `(let ((doom--current-module ',key)) (load! init ,path t))
|
||||||
|
init-forms)
|
||||||
|
(push `(let ((doom--current-module ',key)) (load! config ,path t))
|
||||||
|
config-forms)))
|
||||||
|
doom-modules)
|
||||||
`(let (file-name-handler-alist)
|
`(let (file-name-handler-alist)
|
||||||
(setq doom-modules ',doom-modules)
|
(setq doom-modules ',doom-modules)
|
||||||
,@(nreverse init-forms)
|
,@(nreverse init-forms)
|
||||||
|
@ -533,8 +582,9 @@ MODULES is an malformed plist of modules to load."
|
||||||
(let ((doom--stage 'config))
|
(let ((doom--stage 'config))
|
||||||
,@(nreverse config-forms)
|
,@(nreverse config-forms)
|
||||||
(when doom-private-dir
|
(when doom-private-dir
|
||||||
(load ,(concat doom-private-dir "config")
|
(let ((load-prefer-newer t))
|
||||||
t (not doom-debug-mode))))))))
|
(load ,(expand-file-name "config" doom-private-dir)
|
||||||
|
t (not doom-debug-mode)))))))))
|
||||||
|
|
||||||
(defmacro def-package! (name &rest plist)
|
(defmacro def-package! (name &rest plist)
|
||||||
"A thin wrapper around `use-package'."
|
"A thin wrapper around `use-package'."
|
||||||
|
|
38
core/core.el
38
core/core.el
|
@ -58,6 +58,20 @@ Use this for files that change often, like cache files.")
|
||||||
"Where your private customizations are placed. Must end in a slash. Respects
|
"Where your private customizations are placed. Must end in a slash. Respects
|
||||||
XDG directory conventions if ~/.config/doom exists.")
|
XDG directory conventions if ~/.config/doom exists.")
|
||||||
|
|
||||||
|
;; Doom hooks
|
||||||
|
(defvar doom-pre-init-hook nil
|
||||||
|
"Hooks run after Doom is first initialized; after Doom's core files are
|
||||||
|
loaded, but before your private init.el file or anything else is loaded.")
|
||||||
|
|
||||||
|
(defvar doom-init-hook nil
|
||||||
|
"Hooks run after all init.el files are loaded, including your private and all
|
||||||
|
module init.el files, but before their config.el files are loaded.")
|
||||||
|
|
||||||
|
(defvar doom-post-init-hook nil
|
||||||
|
"A list of hooks run when Doom is fully initialized. Fires at the end of
|
||||||
|
`emacs-startup-hook', as late as possible. Guaranteed to run after everything
|
||||||
|
else (except for `window-setup-hook').")
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;; UTF-8 as the default coding system
|
;; UTF-8 as the default coding system
|
||||||
|
@ -106,22 +120,6 @@ XDG directory conventions if ~/.config/doom exists.")
|
||||||
url-configuration-directory (concat doom-etc-dir "url/"))
|
url-configuration-directory (concat doom-etc-dir "url/"))
|
||||||
|
|
||||||
|
|
||||||
;; Custom init hooks; clearer than `after-init-hook', `emacs-startup-hook', and
|
|
||||||
;; `window-setup-hook'.
|
|
||||||
(defvar doom-pre-init-hook nil
|
|
||||||
"Hooks run after Doom is first initialized; after Doom's core files are
|
|
||||||
loaded, but before your private init.el file or anything else is loaded.")
|
|
||||||
|
|
||||||
(defvar doom-init-hook nil
|
|
||||||
"Hooks run after all init.el files are loaded, including your private and all
|
|
||||||
module init.el files, but before their config.el files are loaded.")
|
|
||||||
|
|
||||||
(defvar doom-post-init-hook nil
|
|
||||||
"A list of hooks run when Doom is fully initialized. Fires at the end of
|
|
||||||
`emacs-startup-hook', as late as possible. Guaranteed to run after everything
|
|
||||||
else (except for `window-setup-hook').")
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Emacs fixes/hacks
|
;; Emacs fixes/hacks
|
||||||
;;
|
;;
|
||||||
|
@ -163,7 +161,7 @@ with functions that require it (like modeline segments)."
|
||||||
(advice-add #'make-indirect-buffer :around #'doom*set-indirect-buffer-filename)
|
(advice-add #'make-indirect-buffer :around #'doom*set-indirect-buffer-filename)
|
||||||
|
|
||||||
;; Truly silence startup message
|
;; Truly silence startup message
|
||||||
(advice-add #'display-startup-echo-area-message :override #'ignore)
|
(fset #'display-startup-echo-area-message #'ignore)
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
@ -202,8 +200,10 @@ this, you'll get stuttering and random freezes) and resets
|
||||||
(require 'core-packages)
|
(require 'core-packages)
|
||||||
(require 'core-os)
|
(require 'core-os)
|
||||||
|
|
||||||
(unless noninteractive
|
(doom-initialize noninteractive)
|
||||||
(doom-initialize))
|
(if noninteractive
|
||||||
|
(require 'core-dispatcher)
|
||||||
|
(doom-initialize-modules))
|
||||||
|
|
||||||
(provide 'core)
|
(provide 'core)
|
||||||
;;; core.el ends here
|
;;; core.el ends here
|
||||||
|
|
2
init.el
2
init.el
|
@ -31,5 +31,3 @@
|
||||||
load-prefer-newer noninteractive)
|
load-prefer-newer noninteractive)
|
||||||
|
|
||||||
(require 'core (concat user-emacs-directory "core/core"))
|
(require 'core (concat user-emacs-directory "core/core"))
|
||||||
(when noninteractive
|
|
||||||
(require 'core-dispatcher))
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue