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 ()
"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
"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)))
(message "Installing core packages...done"))))
;; autoloads file
(unless
(with-demoted-errors "Autoload error: %s"
(let (byte-compile-warnings)
(load doom-autoload-file 'noerror 'nomessage 'nosuffix)))
(unless noninteractive
(error "No autoloads file! Run make autoloads")))
(cl-pushnew doom-core-dir load-path :test #'string=))
(condition-case-unless-debug e
(unless
(let (byte-compile-warnings)
(load (substring doom-autoload-file 0 -3) 'noerror 'nomessage))
(error "No autoloads file! Run make autoloads"))
(error
(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
(require 'core-os)
(unless noninteractive
@ -761,6 +768,7 @@ This should be run whenever init.el or an autoload file is modified. Running
(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)))
@ -776,66 +784,78 @@ This should be run whenever init.el or an autoload file is modified. Running
(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 (list doom-emacs-dir)
doom-psuedo-module-dirs
(load-path (append doom-psuedo-module-dirs
doom-modules-dirs
load-path))
library-cache)
case-fold-search)
;; FIXME Make me faster
(unwind-protect
(condition-case-unless-debug ex
(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")
(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")
(save-excursion
;; Replace autoload paths with absolute paths for faster
;; resolution during load and simpler `load-path'
(while (re-search-forward "^\\s-*(autoload\\s-+'[^ ]+\\s-+\"\\([^/][^\"]*\\)\"" nil t)
(let ((path (match-string 1)))
;; (delete-region (match-beginning 1) (match-end 1))
(replace-match
(or (cdr (assoc path library-cache))
(when-let* ((libpath (locate-library path))
(libpath (file-name-sans-extension libpath)))
(push (cons path libpath) library-cache)
libpath)
(progn
(warn "Couldn't find absolute path for: %s" path)
path))
t t nil 1)))
(message "✓ Autoload paths expanded"))
;; 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"))
(save-excursion
;; insert package autoloads
(dolist (file (doom-packages--files doom-packages-dir "-autoloads\\.el$"))
(insert
(with-temp-buffer
(insert "\n(let ((load-file-name " (prin1-to-string file) "))")
(insert-file-contents file)
(while (re-search-forward "^;;\\(.*\n\\)" nil 'move)
(replace-match "" t t))
(unless (bolp) (insert "\n"))
(insert ")\n")
(buffer-string))))
(message "✓ Package autoloads included"))
;; 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"))
;; Replace autoload paths with absolute paths for faster
;; resolution during load and simpler `load-path'
(while (re-search-forward "^\\s-*(add-to-list\\s-+'\\(?:load-path\\|auto-mode-alist\\)" nil t)
(beginning-of-line-text)
(kill-sexp))
(message "✓ Autoload load-path entries removed")
;; 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")
(save-buffer)
(let (byte-compile-warnings)
;; give the file a chance to reveal errors
(load doom-autoload-file nil 'nomessage 'nosuffix))
(message "Done!"))
('error
(delete-file doom-autoload-file)
(error "Error in autoloads.el: %s -- %s"
(car ex) (error-message-string ex))))
;; 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)