Move batch commands from core-packages to autoload/modules
This commit is contained in:
parent
1d99ee5017
commit
a46e7655dc
2 changed files with 289 additions and 346 deletions
288
core/autoload/modules.el
Normal file
288
core/autoload/modules.el
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
;;; core/autoload/modules.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun doom//reload ()
|
||||||
|
"Reload your private Doom config. Experimental!"
|
||||||
|
(interactive)
|
||||||
|
(let ((load-prefer-newer t))
|
||||||
|
(message "Reloading your private config...")
|
||||||
|
(setq doom-modules (make-hash-table :test #'equal :size 100 :rehash-threshold 1.0))
|
||||||
|
(doom-initialize t)
|
||||||
|
(doom//reload-autoloads))
|
||||||
|
(message "✓ Done!"))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun doom//reload-load-path ()
|
||||||
|
"Reload `load-path' and recompile files (if necessary).
|
||||||
|
|
||||||
|
Use this when `load-path' is out of sync with your plugins. This should only
|
||||||
|
happen if you manually modify/update/install packages from outside Emacs, while
|
||||||
|
an Emacs session is running.
|
||||||
|
|
||||||
|
This isn't necessary if you use Doom's package management commands because they
|
||||||
|
call `doom//reload-load-path' remotely (through emacsclient)."
|
||||||
|
(interactive)
|
||||||
|
(unless doom--inhibit-reload
|
||||||
|
(when (file-exists-p doom-packages-file)
|
||||||
|
(delete-file doom-packages-file))
|
||||||
|
(cond ((and noninteractive (not (daemonp)))
|
||||||
|
(require 'server)
|
||||||
|
(when (server-running-p)
|
||||||
|
(message "Reloading active Emacs session...")
|
||||||
|
(server-eval-at server-name '(doom//reload-load-path))))
|
||||||
|
(t
|
||||||
|
(doom-initialize t)
|
||||||
|
(message "%d packages reloaded" (length package-alist))
|
||||||
|
(run-hooks 'doom-reload-hook)))))
|
||||||
|
|
||||||
|
(defvar generated-autoload-load-name)
|
||||||
|
;;;###autoload
|
||||||
|
(defun doom//reload-autoloads (&optional force)
|
||||||
|
"Refreshes the autoloads.el file, specified by `doom-autoload-file'.
|
||||||
|
|
||||||
|
It scans and reads core/autoload/*.el, modules/*/*/autoload.el and
|
||||||
|
modules/*/*/autoload/*.el, and generates an autoloads file at the path specified
|
||||||
|
by `doom-autoload-file'. This file tells Emacs where to find lazy-loaded
|
||||||
|
functions.
|
||||||
|
|
||||||
|
This should be run whenever init.el or an autoload file is modified. Running
|
||||||
|
'make autoloads' from the commandline executes this command."
|
||||||
|
(interactive)
|
||||||
|
;; This function must not use autoloaded functions or external dependencies.
|
||||||
|
;; It must assume nothing is set up!
|
||||||
|
(let ((default-directory doom-emacs-dir)
|
||||||
|
(targets
|
||||||
|
(file-expand-wildcards
|
||||||
|
(expand-file-name "autoload/*.el" doom-core-dir)))
|
||||||
|
(generate-autoload-section-continuation "")
|
||||||
|
(generate-autoload-section-header "")
|
||||||
|
(generate-autoload-section-trailer "")
|
||||||
|
(doom--stage 'autoloads)
|
||||||
|
outdated)
|
||||||
|
(doom-initialize)
|
||||||
|
(dolist (path (doom-module-load-path))
|
||||||
|
(let ((auto-dir (expand-file-name "autoload" path))
|
||||||
|
(auto-file (expand-file-name "autoload.el" path)))
|
||||||
|
(when (file-exists-p auto-file)
|
||||||
|
(push auto-file targets))
|
||||||
|
(when (file-directory-p auto-dir)
|
||||||
|
(dolist (file (doom-files-under auto-dir :match "\\.el$"))
|
||||||
|
(push file targets)))))
|
||||||
|
(when (file-exists-p doom-autoload-file)
|
||||||
|
(delete-file doom-autoload-file)
|
||||||
|
(ignore-errors (delete-file (byte-compile-dest-file doom-autoload-file)))
|
||||||
|
(message "Deleted old autoloads.el"))
|
||||||
|
(message "Generating new autoloads.el")
|
||||||
|
(dolist (file (mapcar #'file-truename (reverse targets)))
|
||||||
|
(let ((generated-autoload-load-name (file-name-sans-extension file)))
|
||||||
|
(message
|
||||||
|
(cond ((not (doom-file-cookie-p file))
|
||||||
|
"⚠ Ignoring %s")
|
||||||
|
((update-file-autoloads file nil doom-autoload-file)
|
||||||
|
"✕ Nothing in %s")
|
||||||
|
("✓ Scanned %s"))
|
||||||
|
(if (file-in-directory-p file default-directory)
|
||||||
|
(file-relative-name file)
|
||||||
|
(abbreviate-file-name file)))))
|
||||||
|
(make-directory (file-name-directory doom-autoload-file) t)
|
||||||
|
(let ((buf (find-file-noselect doom-autoload-file t))
|
||||||
|
(load-path (append doom-psuedo-module-dirs
|
||||||
|
doom-modules-dirs
|
||||||
|
load-path))
|
||||||
|
case-fold-search)
|
||||||
|
;; FIXME Make me faster
|
||||||
|
(unwind-protect
|
||||||
|
(with-current-buffer buf
|
||||||
|
(goto-char (point-min))
|
||||||
|
(insert ";;; -*- lexical-binding:t -*-\n"
|
||||||
|
";; This file is autogenerated by `doom//reload-autoloads', DO NOT EDIT !!\n\n")
|
||||||
|
|
||||||
|
;; Replace autoload paths (only for module autoloads) with
|
||||||
|
;; absolute paths for faster resolution during load and simpler
|
||||||
|
;; `load-path'
|
||||||
|
(save-excursion
|
||||||
|
(let (cache)
|
||||||
|
(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
|
||||||
|
(save-excursion
|
||||||
|
(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
|
||||||
|
;; of them, at least); they are cached elsewhere, so these are
|
||||||
|
;; unnecessary overhead.
|
||||||
|
(while (re-search-forward (concat "^\\s-*(\\(add-to-list\\s-+'\\(?:load-path\\|auto-mode-alist\\)\\)")
|
||||||
|
nil t)
|
||||||
|
(beginning-of-line)
|
||||||
|
(skip-chars-forward " \t")
|
||||||
|
(kill-sexp))
|
||||||
|
(message "✓ load-path/auto-mode-alist entries removed")
|
||||||
|
|
||||||
|
;; 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
|
||||||
|
(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
|
||||||
|
(defun doom//byte-compile (&optional modules recompile-p)
|
||||||
|
"Byte compiles your emacs configuration.
|
||||||
|
|
||||||
|
init.el is always byte-compiled by this.
|
||||||
|
|
||||||
|
If MODULES is specified (a list of module strings, e.g. \"lang/php\"), those are
|
||||||
|
byte-compiled. Otherwise, all enabled modules are byte-compiled, including Doom
|
||||||
|
core. It always ignores unit tests and files with `no-byte-compile' enabled.
|
||||||
|
|
||||||
|
Doom was designed to benefit from byte-compilation, but the process may take a
|
||||||
|
while. Also, while your config files are byte-compiled, changes to them will not
|
||||||
|
take effect! Use `doom//clean-byte-compiled-files' or `make clean' to remove
|
||||||
|
these files.
|
||||||
|
|
||||||
|
If RECOMPILE-P is non-nil, only recompile out-of-date files."
|
||||||
|
(interactive
|
||||||
|
(list nil current-prefix-arg))
|
||||||
|
(let ((default-directory doom-emacs-dir)
|
||||||
|
(recompile-p (or recompile-p (and (member "-r" (cdr argv)) t)))
|
||||||
|
(argv (delete "-r" argv)))
|
||||||
|
(unless recompile-p
|
||||||
|
(doom//clean-byte-compiled-files))
|
||||||
|
(let ((total-ok 0)
|
||||||
|
(total-fail 0)
|
||||||
|
(total-noop 0)
|
||||||
|
(modules (or modules (cdr argv)))
|
||||||
|
compile-plugins
|
||||||
|
compile-targets)
|
||||||
|
;; Ensure that Doom has been fully loaded, some of its state may be
|
||||||
|
;; pertinent to files compiled later.
|
||||||
|
(let ((doom--stage 'compile)
|
||||||
|
noninteractive)
|
||||||
|
;; Core libraries aren't fully loaded in a noninteractive session, so we
|
||||||
|
;; pretend to be interactive and reinitialize
|
||||||
|
(doom-initialize))
|
||||||
|
;; Assemble el files we want to compile; taking into account that MODULES
|
||||||
|
;; may be a list of MODULE/SUBMODULE strings from the command line.
|
||||||
|
(setq
|
||||||
|
modules (or modules (append (list doom-core-dir) (doom-module-load-path)))
|
||||||
|
compile-targets
|
||||||
|
(cl-loop for target in modules
|
||||||
|
if (equal target ":core")
|
||||||
|
nconc (nreverse (doom-files-under doom-core-dir :match "\\.el$"))
|
||||||
|
and collect (expand-file-name "init.el" doom-private-dir)
|
||||||
|
if (equal target ":private")
|
||||||
|
nconc (nreverse (doom-files-under doom-private-dir :match "\\.el$"))
|
||||||
|
if (equal target ":plugins")
|
||||||
|
do (setq compile-plugins t)
|
||||||
|
else if (file-directory-p target)
|
||||||
|
nconc (nreverse (doom-files-under target :match "\\.el$"))
|
||||||
|
else if (cl-member target doom-psuedo-module-dirs :test #'file-in-directory-p)
|
||||||
|
nconc (nreverse (doom-files-under it :match "\\.el$"))
|
||||||
|
else if (string-match "^\\([^/]+\\)/\\([^/]+\\)$" target)
|
||||||
|
nconc (nreverse (doom-files-under
|
||||||
|
(doom-module-locate-path
|
||||||
|
(intern (format ":%s" (match-string 1 target)))
|
||||||
|
(intern (match-string 2 target)))
|
||||||
|
:match "\\.el$"))
|
||||||
|
else if (file-exists-p target)
|
||||||
|
collect target
|
||||||
|
finally do (setq argv nil)))
|
||||||
|
(if compile-plugins
|
||||||
|
(byte-recompile-directory package-user-dir 0 t)
|
||||||
|
(if (not compile-targets)
|
||||||
|
(message "No targets to compile")
|
||||||
|
(condition-case ex
|
||||||
|
(let ((use-package-expand-minimally t))
|
||||||
|
(push (expand-file-name "init.el" doom-emacs-dir) compile-targets)
|
||||||
|
(dolist (target (cl-delete-duplicates (mapcar #'file-truename compile-targets) :test #'equal))
|
||||||
|
(when (or (not recompile-p)
|
||||||
|
(let ((elc-file (byte-compile-dest-file target)))
|
||||||
|
(and (file-exists-p elc-file)
|
||||||
|
(file-newer-than-file-p target elc-file))))
|
||||||
|
(let ((result (cond ((string-match-p "/\\(packages\\|doctor\\)\\.el$" target)
|
||||||
|
'no-byte-compile)
|
||||||
|
((doom-file-cookie-p target)
|
||||||
|
(byte-compile-file target))
|
||||||
|
('no-byte-compile)))
|
||||||
|
(short-name (if (file-in-directory-p target doom-emacs-dir)
|
||||||
|
(file-relative-name target doom-emacs-dir)
|
||||||
|
(abbreviate-file-name target))))
|
||||||
|
(cl-incf
|
||||||
|
(cond ((eq result 'no-byte-compile)
|
||||||
|
(message! (dark (white "⚠ Ignored %s" short-name)))
|
||||||
|
total-noop)
|
||||||
|
((null result)
|
||||||
|
(message! (red "✕ Failed to compile %s" short-name))
|
||||||
|
total-fail)
|
||||||
|
(t
|
||||||
|
(message! (green "✓ Compiled %s" short-name))
|
||||||
|
(quiet! (load target t t))
|
||||||
|
total-ok))))))
|
||||||
|
(message!
|
||||||
|
(bold
|
||||||
|
(color (if (= total-fail 0) 'green 'red)
|
||||||
|
"%s %d/%d file(s) (%d ignored)"
|
||||||
|
(if recompile-p "Recompiled" "Compiled")
|
||||||
|
total-ok (- (length compile-targets) total-noop)
|
||||||
|
total-noop))))
|
||||||
|
(error
|
||||||
|
(message! (red "\n%%s\n\n%%s\n\n%%s")
|
||||||
|
"There were breaking errors."
|
||||||
|
(error-message-string ex)
|
||||||
|
"Reverting changes...")
|
||||||
|
(quiet! (doom//clean-byte-compiled-files))
|
||||||
|
(message! (green "Finished (nothing was byte-compiled)")))))))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun doom//clean-byte-compiled-files ()
|
||||||
|
"Delete all the compiled elc files in your Emacs configuration. This excludes
|
||||||
|
compiled packages.'"
|
||||||
|
(interactive)
|
||||||
|
(cl-loop with default-directory = doom-emacs-dir
|
||||||
|
for path in (append (doom-files-in doom-emacs-dir :match "\\.elc$")
|
||||||
|
(doom-files-in doom-psuedo-module-dirs :match "\\.elc$" :full t)
|
||||||
|
(doom-files-under doom-core-dir :match "\\.elc$")
|
||||||
|
(doom-files-under doom-modules-dirs :match "\\.elc$"))
|
||||||
|
for truepath = (file-truename path)
|
||||||
|
do (delete-file path)
|
||||||
|
and do
|
||||||
|
(message "✓ Deleted %s"
|
||||||
|
(if (file-in-directory-p truepath default-directory)
|
||||||
|
(file-relative-name truepath)
|
||||||
|
(abbreviate-file-name path)))
|
||||||
|
finally do (message "Everything is clean")))
|
|
@ -717,352 +717,7 @@ loads MODULE SUBMODULE's packages.el file."
|
||||||
(flags ,flags))
|
(flags ,flags))
|
||||||
(when flags
|
(when flags
|
||||||
(doom-module-put ,module ',submodule :flags flags))
|
(doom-module-put ,module ',submodule :flags flags))
|
||||||
(load! packages ,(doom-module-find-path module submodule) t)))
|
(load! packages ,(doom-module-locate-path module submodule) t)))
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Commands
|
|
||||||
;;
|
|
||||||
|
|
||||||
(defun doom//reload ()
|
|
||||||
"Reload your private Doom config. Experimental!"
|
|
||||||
(interactive)
|
|
||||||
(message "Reloading your private config...")
|
|
||||||
(load (concat doom-private-dir "init.el") nil nil 'nosuffix)
|
|
||||||
(doom-packages--async-run #'doom//reload-packages)
|
|
||||||
(let ((doom--stage 'config))
|
|
||||||
(load (concat doom-private-dir "config.el") nil nil 'nosuffix))
|
|
||||||
(message "✓ Done!"))
|
|
||||||
|
|
||||||
(defun doom-packages--read-if-cookies (file)
|
|
||||||
"Returns the value of the ;;;###if predicate form in FILE."
|
|
||||||
(with-temp-buffer
|
|
||||||
(insert-file-contents-literally file nil 0 256)
|
|
||||||
(if (and (re-search-forward "^;;;###if " nil t)
|
|
||||||
(<= (line-number-at-pos) 3))
|
|
||||||
(let ((load-file-name file))
|
|
||||||
(eval (sexp-at-point)))
|
|
||||||
t)))
|
|
||||||
|
|
||||||
(defun doom-packages--async-run (fn)
|
|
||||||
(let* ((default-directory doom-emacs-dir))
|
|
||||||
(compile (format "%s --quick --batch -l core/core.el -f %s"
|
|
||||||
(executable-find "emacs")
|
|
||||||
(symbol-name fn)))
|
|
||||||
(while compilation-in-progress
|
|
||||||
(sit-for 1))))
|
|
||||||
|
|
||||||
(defun doom-packages--files (dir pattern)
|
|
||||||
"Like `directory-files-recursively', but traverses symlinks."
|
|
||||||
(cl-letf (((symbol-function #'file-symlink-p) #'ignore))
|
|
||||||
(directory-files-recursively dir pattern)))
|
|
||||||
|
|
||||||
(defun doom//reload-load-path ()
|
|
||||||
"Reload `load-path' and recompile files (if necessary).
|
|
||||||
|
|
||||||
Use this when `load-path' is out of sync with your plugins. This should only
|
|
||||||
happen if you manually modify/update/install packages from outside Emacs, while
|
|
||||||
an Emacs session is running.
|
|
||||||
|
|
||||||
This isn't necessary if you use Doom's package management commands because they
|
|
||||||
call `doom//reload-load-path' remotely (through emacsclient)."
|
|
||||||
(interactive)
|
|
||||||
(unless doom--inhibit-reload
|
|
||||||
(when (file-exists-p doom-packages-file)
|
|
||||||
(delete-file doom-packages-file))
|
|
||||||
(cond ((and noninteractive (not (daemonp)))
|
|
||||||
(require 'server)
|
|
||||||
(when (server-running-p)
|
|
||||||
(message "Reloading active Emacs session...")
|
|
||||||
(server-eval-at server-name '(doom//reload-load-path))))
|
|
||||||
(t
|
|
||||||
(doom-initialize t)
|
|
||||||
(message "%d packages reloaded" (length package-alist))
|
|
||||||
(run-hooks 'doom-reload-hook)))))
|
|
||||||
|
|
||||||
(defvar generated-autoload-load-name)
|
|
||||||
(defun doom//reload-autoloads ()
|
|
||||||
"Refreshes the autoloads.el file, specified by `doom-autoload-file'.
|
|
||||||
|
|
||||||
It scans and reads core/autoload/*.el, modules/*/*/autoload.el and
|
|
||||||
modules/*/*/autoload/*.el, and generates an autoloads file at the path specified
|
|
||||||
by `doom-autoload-file'. This file tells Emacs where to find lazy-loaded
|
|
||||||
functions.
|
|
||||||
|
|
||||||
This should be run whenever init.el or an autoload file is modified. Running
|
|
||||||
'make autoloads' from the commandline executes this command."
|
|
||||||
(interactive)
|
|
||||||
;; This function must not use autoloaded functions or external dependencies.
|
|
||||||
;; It must assume nothing is set up!
|
|
||||||
(if (not noninteractive)
|
|
||||||
;; This is done in another instance to protect the current session's state
|
|
||||||
;; in case this function has side effects.
|
|
||||||
(progn
|
|
||||||
(doom-packages--async-run 'doom//reload-autoloads)
|
|
||||||
(load doom-autoload-file 'noerror nil 'nosuffix))
|
|
||||||
(let ((default-directory doom-emacs-dir)
|
|
||||||
(targets
|
|
||||||
(file-expand-wildcards
|
|
||||||
(expand-file-name "autoload/*.el" doom-core-dir))))
|
|
||||||
(dolist (path (doom-module-load-path))
|
|
||||||
(let ((auto-dir (expand-file-name "autoload" path))
|
|
||||||
(auto-file (expand-file-name "autoload.el" path)))
|
|
||||||
(when (file-exists-p auto-file)
|
|
||||||
(push auto-file targets))
|
|
||||||
(when (file-directory-p auto-dir)
|
|
||||||
(dolist (file (doom-packages--files auto-dir "\\.el$"))
|
|
||||||
(push file targets)))))
|
|
||||||
(when (file-exists-p doom-autoload-file)
|
|
||||||
(delete-file doom-autoload-file)
|
|
||||||
(ignore-errors (delete-file (byte-compile-dest-file doom-autoload-file)))
|
|
||||||
(message "Deleted old autoloads.el"))
|
|
||||||
(message "Generating new autoloads.el")
|
|
||||||
(dolist (file (mapcar #'file-truename (reverse targets)))
|
|
||||||
(let ((generated-autoload-load-name (file-name-sans-extension file)))
|
|
||||||
(message
|
|
||||||
(cond ((not (doom-packages--read-if-cookies file))
|
|
||||||
"⚠ Ignoring %s")
|
|
||||||
((update-file-autoloads file nil doom-autoload-file)
|
|
||||||
"✕ Nothing in %s")
|
|
||||||
("✓ Scanned %s"))
|
|
||||||
(if (file-in-directory-p file default-directory)
|
|
||||||
(file-relative-name file)
|
|
||||||
(abbreviate-file-name file)))))
|
|
||||||
(make-directory (file-name-directory doom-autoload-file) t)
|
|
||||||
(let ((buf (find-file-noselect doom-autoload-file t))
|
|
||||||
(load-path (append doom-psuedo-module-dirs
|
|
||||||
doom-modules-dirs
|
|
||||||
load-path))
|
|
||||||
case-fold-search)
|
|
||||||
;; FIXME Make me faster
|
|
||||||
(unwind-protect
|
|
||||||
(with-current-buffer buf
|
|
||||||
(goto-char (point-min))
|
|
||||||
(insert ";;; -*- lexical-binding:t -*-\n"
|
|
||||||
";; This file is autogenerated by `doom//reload-autoloads', DO NOT EDIT !!\n\n")
|
|
||||||
|
|
||||||
;; Replace autoload paths (only for module autoloads) with
|
|
||||||
;; absolute paths for faster resolution during load and simpler
|
|
||||||
;; `load-path'
|
|
||||||
(save-excursion
|
|
||||||
(let (cache)
|
|
||||||
(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 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
|
|
||||||
(save-excursion
|
|
||||||
(dolist (spec package-alist)
|
|
||||||
(let ((pkg (car spec)))
|
|
||||||
(unless (memq pkg doom-autoload-excluded-packages)
|
|
||||||
(let ((file (concat (package--autoloads-file-name (cadr spec)) ".el")))
|
|
||||||
(insert "(let ((load-file-name " (prin1-to-string file) "))")
|
|
||||||
(insert-file-contents file)
|
|
||||||
(while (re-search-forward "^;;\\(.*\n\\)" nil t)
|
|
||||||
(replace-match "" t t))
|
|
||||||
(unless (bolp) (insert "\n"))
|
|
||||||
(insert ")\n")))))
|
|
||||||
(message "✓ Package autoloads included"))
|
|
||||||
|
|
||||||
;; Remove `load-path' and `auto-mode-alist' modifications (most
|
|
||||||
;; of them, at least); they are cached elsewhere, so these are
|
|
||||||
;; unnecessary overhead.
|
|
||||||
(while (re-search-forward (concat "^\\s-*(\\("
|
|
||||||
"add-to-list\\s-+'\\(?:load-path\\|auto-mode-alist\\)\\|"
|
|
||||||
"if (fboundp 'register-definition-prefixes)"
|
|
||||||
"\\)")
|
|
||||||
nil t)
|
|
||||||
(beginning-of-line)
|
|
||||||
(skip-chars-forward " \t")
|
|
||||||
(kill-sexp))
|
|
||||||
(message "✓ load-path/auto-mode-alist entries removed")
|
|
||||||
|
|
||||||
;; 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
|
|
||||||
(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))))))
|
|
||||||
|
|
||||||
(defun doom//byte-compile (&optional modules recompile-p)
|
|
||||||
"Byte compiles your emacs configuration.
|
|
||||||
|
|
||||||
init.el is always byte-compiled by this.
|
|
||||||
|
|
||||||
If MODULES is specified (a list of module strings, e.g. \"lang/php\"), those are
|
|
||||||
byte-compiled. Otherwise, all enabled modules are byte-compiled, including Doom
|
|
||||||
core. It always ignores unit tests and files with `no-byte-compile' enabled.
|
|
||||||
|
|
||||||
Doom was designed to benefit from byte-compilation, but the process may take a
|
|
||||||
while. Also, while your config files are byte-compiled, changes to them will not
|
|
||||||
take effect! Use `doom//clean-byte-compiled-files' or `make clean' to remove
|
|
||||||
these files.
|
|
||||||
|
|
||||||
If RECOMPILE-P is non-nil, only recompile out-of-date files."
|
|
||||||
(interactive
|
|
||||||
(list nil current-prefix-arg))
|
|
||||||
(let ((default-directory doom-emacs-dir)
|
|
||||||
(recompile-p (or recompile-p (and (member "-r" (cdr argv)) t)))
|
|
||||||
(argv (delete "-r" argv)))
|
|
||||||
(if (not noninteractive)
|
|
||||||
;; This is done in another instance to protect the current session's
|
|
||||||
;; state, because this function has side effects.
|
|
||||||
(doom-packages--async-run 'doom//byte-compile)
|
|
||||||
(let ((total-ok 0)
|
|
||||||
(total-fail 0)
|
|
||||||
(total-noop 0)
|
|
||||||
(modules (or modules (cdr argv)))
|
|
||||||
compile-targets)
|
|
||||||
;; Ensure that Doom has been fully loaded, some of its state may be
|
|
||||||
;; pertinent to files compiled later.
|
|
||||||
(let (noninteractive)
|
|
||||||
;; Core libraries aren't fully loaded in a noninteractive session, so
|
|
||||||
;; we pretend to be interactive and reinitialize
|
|
||||||
(doom-initialize)
|
|
||||||
;; In case autoloads.el hasn't been properly generated at this point.
|
|
||||||
(unless (file-exists-p doom-autoload-file)
|
|
||||||
(mapc #'load (file-expand-wildcards (expand-file-name "autoload/*.el" doom-core-dir)))))
|
|
||||||
;; Assemble el files we want to compile; taking into account that
|
|
||||||
;; MODULES may be a list of MODULE/SUBMODULE strings from the command
|
|
||||||
;; line.
|
|
||||||
(setq compile-targets
|
|
||||||
(cl-loop for target
|
|
||||||
in (or modules (append (list doom-core-dir) (doom-module-load-path)))
|
|
||||||
if (equal target "core")
|
|
||||||
nconc (nreverse (doom-packages--files doom-core-dir "\\.el$"))
|
|
||||||
and collect (expand-file-name "init.el" doom-private-dir)
|
|
||||||
else if (file-directory-p target)
|
|
||||||
nconc (nreverse (doom-packages--files target "\\.el$"))
|
|
||||||
else if (cl-member target doom-psuedo-module-dirs :test #'file-in-directory-p)
|
|
||||||
nconc (nreverse (doom-packages--files it "\\.el$"))
|
|
||||||
else if (string-match "^\\([^/]+\\)/\\([^/]+\\)$" target)
|
|
||||||
nconc (nreverse (doom-packages--files
|
|
||||||
(doom-module-find-path
|
|
||||||
(intern (format ":%s" (match-string 1 target)))
|
|
||||||
(intern (match-string 2 target)))
|
|
||||||
"\\.el$"))
|
|
||||||
else if (file-exists-p target)
|
|
||||||
collect target
|
|
||||||
finally do (setq argv nil)))
|
|
||||||
(if (not compile-targets)
|
|
||||||
(message "No targets to compile")
|
|
||||||
(condition-case ex
|
|
||||||
(let ((use-package-expand-minimally t))
|
|
||||||
(push (expand-file-name "init.el" doom-emacs-dir) compile-targets)
|
|
||||||
(dolist (target (cl-delete-duplicates (mapcar #'file-truename compile-targets) :test #'equal))
|
|
||||||
(when (and (not (string-match-p "/\\(packages\\|doctor\\)\\.el$" target))
|
|
||||||
(or (not recompile-p)
|
|
||||||
(let ((elc-file (byte-compile-dest-file target)))
|
|
||||||
(and (file-exists-p elc-file)
|
|
||||||
(file-newer-than-file-p target elc-file)))))
|
|
||||||
(let ((result (if (doom-packages--read-if-cookies target)
|
|
||||||
(byte-compile-file target)
|
|
||||||
'no-byte-compile))
|
|
||||||
(short-name (if (file-in-directory-p target doom-emacs-dir)
|
|
||||||
(file-relative-name target doom-emacs-dir)
|
|
||||||
(abbreviate-file-name target))))
|
|
||||||
(cl-incf
|
|
||||||
(cond ((eq result 'no-byte-compile)
|
|
||||||
(message! (dark (white "⚠ Ignored %s" short-name)))
|
|
||||||
total-noop)
|
|
||||||
((null result)
|
|
||||||
(message! (red "✕ Failed to compile %s" short-name))
|
|
||||||
total-fail)
|
|
||||||
(t
|
|
||||||
(message! (green "✓ Compiled %s" short-name))
|
|
||||||
(quiet! (load target t t))
|
|
||||||
total-ok))))))
|
|
||||||
(message!
|
|
||||||
(bold
|
|
||||||
(color (if (= total-fail 0) 'green 'red)
|
|
||||||
"%s %s file(s) %s"
|
|
||||||
(if recompile-p "Recompiled" "Compiled")
|
|
||||||
(format "%d/%d" total-ok (- (length compile-targets) total-noop))
|
|
||||||
(format "(%s ignored)" total-noop)))))
|
|
||||||
(error
|
|
||||||
(message! (red "\n%%s\n\n%%s\n\n%%s")
|
|
||||||
"There were breaking errors."
|
|
||||||
(error-message-string ex)
|
|
||||||
"Reverting changes...")
|
|
||||||
(quiet! (doom//clean-byte-compiled-files))
|
|
||||||
(message! (green "Finished (nothing was byte-compiled)")))))))))
|
|
||||||
|
|
||||||
(defun doom//byte-compile-core (&optional recompile-p)
|
|
||||||
"Byte compile the core Doom files.
|
|
||||||
|
|
||||||
This is faster than `doom//byte-compile', still yields considerable performance
|
|
||||||
benefits, and is more reliable in an ever-changing Emacs config (since you won't
|
|
||||||
likely change core files directly).
|
|
||||||
|
|
||||||
If RECOMPILE-P is non-nil, only recompile out-of-date core files."
|
|
||||||
(interactive "P")
|
|
||||||
(if (not noninteractive)
|
|
||||||
;; This is done in another instance to protect the current session's
|
|
||||||
;; state. `doom-initialize-packages' will have side effects otherwise.
|
|
||||||
(doom-packages--async-run 'doom//byte-compile-core)
|
|
||||||
(doom//byte-compile (list "core") recompile-p)))
|
|
||||||
|
|
||||||
(defun doom//byte-recompile-plugins ()
|
|
||||||
"Recompile all installed plugins. If you're getting odd errors after upgrading
|
|
||||||
(or downgrading) Emacs, this may fix it."
|
|
||||||
(interactive)
|
|
||||||
(if (not noninteractive)
|
|
||||||
;; This is done in another instance to protect the current session's
|
|
||||||
;; state. `doom-initialize-packages' will have side effects otherwise.
|
|
||||||
(doom-packages--async-run 'doom//byte-recompile-plugins)
|
|
||||||
(byte-recompile-directory package-user-dir 0 t)))
|
|
||||||
|
|
||||||
(defun doom//clean-byte-compiled-files ()
|
|
||||||
"Delete all the compiled elc files in your Emacs configuration. This excludes
|
|
||||||
compiled packages.'"
|
|
||||||
(interactive)
|
|
||||||
(unless
|
|
||||||
(cl-loop with default-directory = doom-emacs-dir
|
|
||||||
for path
|
|
||||||
in (append (file-expand-wildcards "*.elc" t)
|
|
||||||
(doom-packages--files doom-core-dir "\\.elc$")
|
|
||||||
(cl-loop for dir in (doom-module-load-path)
|
|
||||||
nconc (doom-packages--files dir "\\.elc$")))
|
|
||||||
for truepath = (file-truename path)
|
|
||||||
if (file-exists-p truepath)
|
|
||||||
collect path
|
|
||||||
and do (delete-file truepath)
|
|
||||||
and do
|
|
||||||
(message "✓ Deleted %s"
|
|
||||||
(if (file-in-directory-p truepath default-directory)
|
|
||||||
(file-relative-name truepath)
|
|
||||||
(abbreviate-file-name path))))
|
|
||||||
(message "Everything is clean")))
|
|
||||||
|
|
||||||
(defun doom//reload-packages ()
|
|
||||||
"Runs `doom//reload-autoloads', `doom//packages-autoremove' and
|
|
||||||
`doom//packages-install' before reloading your Emacs session."
|
|
||||||
(interactive)
|
|
||||||
(let ((doom--inhibit-reload t))
|
|
||||||
(doom//packages-autoremove)
|
|
||||||
(doom//packages-install)
|
|
||||||
(doom//reload-autoloads))
|
|
||||||
(doom//reload-load-path))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue