diff --git a/init.el b/init.el index 5f2787de..aa7d6efd 100644 --- a/init.el +++ b/init.el @@ -181,6 +181,33 @@ Set to stable melpa.org if you want stable.") (setq package-native-compile (native-comp-available-p))) (package-initialize) + +;; When a package is installed the heavy lifting is done by +;; `package-install-from-archive' and `package-unpack'. The latter calls +;; `package-activate-1', then compiles the package, and then calls +;; `package--reload-previously-loaded' (or `package--load-files-for-activation' +;; until Emacs-28). However, `packgage-activate-1' also calls +;; `package--reload-previously-loaded' (or `package--load-files-for-activation' +;; until Emacs-28) and only after that adds the newly installed package's +;; directory to `load-path'. This however may be not sufficient when some +;; files `require' files from the package. Ensure such `require'd files are +;; visible for the latter call, and allow the original `load-path' to be +;; updated by the former (likely when loading package autoloads). +(defun exordium--ensure-pkg-dir-in-load-path (pkg-desc &rest _ignore) + "Ensure PKG-DESC directory is in `load-path'." + (when-let* (((package-desc-p pkg-desc)) + (pkg-dir (package-desc-dir pkg-desc))) + (unless (or (member (file-name-as-directory pkg-dir) load-path) + (member (directory-file-name pkg-dir) load-path)) + (push pkg-dir load-path)))) +(cond + ((fboundp 'package--reload-previously-loaded) ;; Since Emacs-29 + (advice-add 'package--reload-previously-loaded + :before #'exordium--ensure-pkg-dir-in-load-path)) + ((fboundp 'package--load-files-for-activation) ;; Until Emacs-28 + (advice-add 'package--load-files-for-activation + :before #'exordium--ensure-pkg-dir-in-load-path))) + ;; Load the packages we need if they are not installed already (let ((package-pinned-packages (append diff --git a/modules/init-lib.el b/modules/init-lib.el index 874ccaf3..49a2cdc2 100644 --- a/modules/init-lib.el +++ b/modules/init-lib.el @@ -123,49 +123,8 @@ It makes buffer local variable with an extra back tick added." ((version-list-< builtin-version archive-version))) (use-package-pin-package package ,archive) (condition-case-unless-debug err - (let* ((package-install-upgrade-built-in t) - (transaction (package-compute-transaction - (list pkg-desc) - (package-desc-reqs pkg-desc))) - (transaction-load-path (mapcar - (lambda (desc) - (expand-file-name - (package-desc-full-name desc) - package-user-dir)) - transaction)) - (with-load-path - (lambda (orig-fun &rest args) - (let (new-load-path) - ;; Ensure the newly installed package and its - ;; dependencies are is in `load-path', when they are - ;; reloaded. - (let ((load-path (append transaction-load-path load-path))) - (apply orig-fun args) - (setq new-load-path load-path)) - ;; After reload, ensure all directories that were added - ;; during reload are in the original `load-path'. - (dolist (dir new-load-path) - (unless (or (member dir transaction-load-path) - (member dir load-path)) - (push dir load-path))))))) - (unwind-protect - (progn - ;; `packgage-activate-1' calls - ;; `package--reload-previously-loaded' and then adds the - ;; newly installed package's directory to `load-path'. This - ;; however may be not sufficient when some files `require' - ;; files from the package. Ensure such `require'd files are - ;; visible for the latter call, and allow the original - ;; `load-path' to be updated by the former (likely when - ;; loading package autoloads). - (advice-add 'package--reload-previously-loaded - :around - with-load-path) - (package-download-transaction transaction) - (package--quickstart-maybe-refresh) - t) - (advice-remove 'package--reload-previously-loaded - with-load-path))) + (let* ((package-install-upgrade-built-in t)) + (package-install pkg-desc)) (error (display-warning 'use-package (format "Failed to force ELPA installation %s: %s"