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
(condition-case-unless-debug e
(unless (unless
(with-demoted-errors "Autoload error: %s"
(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")
;; Replace autoload paths (only for module autoloads) with
;; absolute paths for faster resolution during load and simpler
;; `load-path'
(save-excursion (save-excursion
;; Replace autoload paths with absolute paths for faster (let (cache)
;; resolution during load and simpler `load-path'
(while (re-search-forward "^\\s-*(autoload\\s-+'[^ ]+\\s-+\"\\([^/][^\"]*\\)\"" nil t) (while (re-search-forward "^\\s-*(autoload\\s-+'[^ ]+\\s-+\"\\([^/][^\"]*\\)\"" nil t)
(let ((path (match-string 1))) (let ((path (match-string 1)))
;; (delete-region (match-beginning 1) (match-end 1))
(replace-match (replace-match
(or (cdr (assoc path library-cache)) (or (cdr (assoc path cache))
(when-let* ((libpath (locate-library path)) (when-let* ((libpath (locate-library path))
(libpath (file-name-sans-extension libpath))) (libpath (file-name-sans-extension libpath)))
(push (cons path libpath) library-cache) (push (cons path libpath) cache)
libpath) libpath)
(progn (progn
(warn "Couldn't find absolute path for: %s" path) (warn "Couldn't find absolute path for: %s" path)
path)) path))
t t nil 1))) t t nil 1))))
(message "✓ Autoload paths expanded")) (message "✓ Autoload paths expanded"))
(save-excursion
;; insert package autoloads ;; insert package autoloads
(dolist (file (doom-packages--files doom-packages-dir "-autoloads\\.el$")) (save-excursion
(insert (dolist (spec package-alist)
(with-temp-buffer (let ((pkg (car spec)))
(insert "\n(let ((load-file-name " (prin1-to-string file) "))") (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) (insert-file-contents file)
(while (re-search-forward "^;;\\(.*\n\\)" nil 'move) (while (re-search-forward "^;;\\(.*\n\\)" nil t)
(replace-match "" t t)) (replace-match "" t t))
(unless (bolp) (insert "\n")) (unless (bolp) (insert "\n"))
(insert ")\n") (insert ")\n")))))
(buffer-string))))
(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-*(\\("
"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)) (kill-sexp))
(message "✓ Autoload load-path entries removed") (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) (save-buffer)
(let (byte-compile-warnings)
;; give the file a chance to reveal errors ;; Byte compile it to give the file a chance to reveal errors.
(load doom-autoload-file nil 'nomessage 'nosuffix)) (condition-case-unless-debug ex
(message "Done!")) (quiet! (byte-compile-file doom-autoload-file 'load))
('error ('error
(delete-file doom-autoload-file) (delete-file doom-autoload-file)
(message "Deleting autoloads file!")
(error "Error in autoloads.el: %s -- %s" (error "Error in autoloads.el: %s -- %s"
(car ex) (error-message-string ex)))) (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)