Rewrite & optimize autoload generation logic

Now includes package autoloads (which allows us to shed some fat from
various module configs, but that'll come later).
This commit is contained in:
Henrik Lissner 2018-05-18 01:09:13 +02:00
parent 82f9fb7027
commit 340aa0449c
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395

View file

@ -75,6 +75,11 @@ 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-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.")
@ -236,13 +241,15 @@ FORCE-P is non-nil, do it anyway.
(error "✕ Couldn't install %s" package))) (error "✕ Couldn't install %s" package)))
(message "Installing core packages...done")))) (message "Installing core packages...done"))))
;; autoloads file ;; autoloads file
(unless (condition-case-unless-debug e
(with-demoted-errors "Autoload error: %s" (unless
(let (byte-compile-warnings) (let (byte-compile-warnings)
(load doom-autoload-file 'noerror 'nomessage 'nosuffix))) (load (substring doom-autoload-file 0 -3) 'noerror 'nomessage))
(unless noninteractive (error "No autoloads file! Run make autoloads"))
(error "No autoloads file! Run make autoloads"))) (error
(cl-pushnew doom-core-dir load-path :test #'string=)) (funcall (if noninteractive #'warn #'error)
"Autoload file error: %s -> %s" (car e) (error-message-string e))))
(add-to-list 'load-path doom-core-dir))
;; initialize Doom core ;; initialize Doom core
(require 'core-os) (require 'core-os)
(unless noninteractive (unless noninteractive
@ -761,6 +768,7 @@ This should be run whenever init.el or an autoload file is modified. Running
(push file targets))))) (push file targets)))))
(when (file-exists-p doom-autoload-file) (when (file-exists-p doom-autoload-file)
(delete-file 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 "Deleted old autoloads.el"))
(message "Generating new autoloads.el") (message "Generating new autoloads.el")
(dolist (file (mapcar #'file-truename (reverse targets))) (dolist (file (mapcar #'file-truename (reverse targets)))
@ -776,66 +784,78 @@ This should be run whenever init.el or an autoload file is modified. Running
(abbreviate-file-name file))))) (abbreviate-file-name file)))))
(make-directory (file-name-directory doom-autoload-file) t) (make-directory (file-name-directory doom-autoload-file) t)
(let ((buf (find-file-noselect doom-autoload-file t)) (let ((buf (find-file-noselect doom-autoload-file t))
(load-path (append (list doom-emacs-dir) (load-path (append doom-psuedo-module-dirs
doom-psuedo-module-dirs
doom-modules-dirs doom-modules-dirs
load-path)) load-path))
library-cache) case-fold-search)
;; FIXME Make me faster
(unwind-protect (unwind-protect
(condition-case-unless-debug ex (with-current-buffer buf
(with-current-buffer buf (goto-char (point-min))
(goto-char (point-min)) (insert ";;; -*- lexical-binding:t -*-\n"
(insert ";;; -*- lexical-binding:t -*-\n" ";; This file is autogenerated by `doom//reload-autoloads', DO NOT EDIT !!\n\n")
";; This file is autogenerated by `doom//reload-autoloads', DO NOT EDIT !!\n\n")
(save-excursion ;; Replace autoload paths (only for module autoloads) with
;; Replace autoload paths with absolute paths for faster ;; absolute paths for faster resolution during load and simpler
;; resolution during load and simpler `load-path' ;; `load-path'
(while (re-search-forward "^\\s-*(autoload\\s-+'[^ ]+\\s-+\"\\([^/][^\"]*\\)\"" nil t) (save-excursion
(let ((path (match-string 1))) (let (cache)
;; (delete-region (match-beginning 1) (match-end 1)) (while (re-search-forward "^\\s-*(autoload\\s-+'[^ ]+\\s-+\"\\([^/][^\"]*\\)\"" nil t)
(replace-match (let ((path (match-string 1)))
(or (cdr (assoc path library-cache)) (replace-match
(when-let* ((libpath (locate-library path)) (or (cdr (assoc path cache))
(libpath (file-name-sans-extension libpath))) (when-let* ((libpath (locate-library path))
(push (cons path libpath) library-cache) (libpath (file-name-sans-extension libpath)))
libpath) (push (cons path libpath) cache)
(progn libpath)
(warn "Couldn't find absolute path for: %s" path) (progn
path)) (warn "Couldn't find absolute path for: %s" path)
t t nil 1))) path))
(message "✓ Autoload paths expanded")) t t nil 1))))
(message "✓ Autoload paths expanded"))
(save-excursion ;; insert package autoloads
;; insert package autoloads (save-excursion
(dolist (file (doom-packages--files doom-packages-dir "-autoloads\\.el$")) (dolist (spec package-alist)
(insert (let ((pkg (car spec)))
(with-temp-buffer (unless (memq pkg doom-autoload-excluded-packages)
(insert "\n(let ((load-file-name " (prin1-to-string file) "))") (let ((file (concat (package--autoloads-file-name (cadr spec)) ".el")))
(insert-file-contents file) (insert "(let ((load-file-name " (prin1-to-string file) "))")
(while (re-search-forward "^;;\\(.*\n\\)" nil 'move) (insert-file-contents file)
(replace-match "" t t)) (while (re-search-forward "^;;\\(.*\n\\)" nil t)
(unless (bolp) (insert "\n")) (replace-match "" t t))
(insert ")\n") (unless (bolp) (insert "\n"))
(buffer-string)))) (insert ")\n")))))
(message "✓ Package autoloads included")) (message "✓ Package autoloads included"))
;; Replace autoload paths with absolute paths for faster ;; Remove `load-path' and `auto-mode-alist' modifications (most
;; resolution during load and simpler `load-path' ;; of them, at least); they are cached elsewhere, so these are
(while (re-search-forward "^\\s-*(add-to-list\\s-+'\\(?:load-path\\|auto-mode-alist\\)" nil t) ;; unnecessary overhead.
(beginning-of-line-text) (while (re-search-forward (concat "^\\s-*(\\("
(kill-sexp)) "add-to-list\\s-+'\\(?:load-path\\|auto-mode-alist\\)\\|"
(message "✓ Autoload load-path entries removed") "if (fboundp 'register-definition-prefixes)"
"\\)")
nil t)
(beginning-of-line)
(skip-chars-forward " \t")
(kill-sexp))
(message "✓ load-path/auto-mode-alist entries removed")
(save-buffer) ;; Remove byte-compile inhibiting file variables so we can
(let (byte-compile-warnings) ;; byte-compile the file.
;; give the file a chance to reveal errors (when (re-search-forward "^;; no-byte-compile: t\n$" nil t)
(load doom-autoload-file nil 'nomessage 'nosuffix)) (replace-match "" t t))
(message "Done!")) (save-buffer)
('error
(delete-file doom-autoload-file) ;; Byte compile it to give the file a chance to reveal errors.
(error "Error in autoloads.el: %s -- %s" (condition-case-unless-debug ex
(car ex) (error-message-string 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)))))) (kill-buffer buf))))))
(defun doom//byte-compile (&optional modules recompile-p) (defun doom//byte-compile (&optional modules recompile-p)