diff --git a/core/autoload/packages.el b/core/autoload/packages.el index 140671e0c..b2879f71a 100644 --- a/core/autoload/packages.el +++ b/core/autoload/packages.el @@ -27,21 +27,18 @@ (persistent-soft-store 'last-pkg-refresh nil "emacs")) ;;;###autoload -(defun doom-package-backend (name) - "Get which backend the package NAME was installed with. Can either be elpa, -quelpa or nil (if not installed)." +(defun doom-package-backend (name &optional noerror) + "Get which backend the package NAME was installed with. Can either be elpa or +quelpa. Throws an error if NOERROR is nil and the package isn't installed." (cl-assert (symbolp name) t) - (doom-initialize-packages) - (cond ((let ((plist (cdr (assq name doom-packages)))) - (and (not (plist-get plist :pin)) - (or (quelpa-setup-p) - (error "Could not initialize quelpa")) - (or (assq name quelpa-cache) - (plist-get plist :recipe)))) + (doom-initialize) + (cond ((and (or (quelpa-setup-p) + (error "Could not initialize quelpa")) + (assq name quelpa-cache)) 'quelpa) ((assq name package-alist) 'elpa) - (t + ((not noerror) (error "%s package not installed" name)))) ;;;###autoload @@ -79,6 +76,18 @@ list of the package." (doom-initialize-packages) (plist-get (cdr (assq name doom-packages)) prop)) +;;;###autoload +(defun doom-package-different-backend-p (name) + "Return t if NAME (a package's symbol) has a new backend than what it was +installed with. Returns nil otherwise, or if package isn't installed." + (cl-assert (symbolp name) t) + (doom-initialize-packages) + (and (package-installed-p name) + (let* ((plist (cdr (assq name doom-packages))) + (old-backend (doom-package-backend name t)) + (new-backend (if (plist-get plist :recipe) 'quelpa 'elpa))) + (not (eq old-backend new-backend))))) + ;;;###autoload (defun doom-get-packages (&optional installed-only-p) "Retrieves a list of explicitly installed packages (i.e. non-dependencies). @@ -129,7 +138,8 @@ Used by `doom/packages-update'." (let ((sym (car pkg))) (when (and (or (not (doom-package-prop sym :freeze)) include-frozen-p) - (not (doom-package-prop sym :ignore))) + (not (doom-package-prop sym :ignore)) + (not (doom-package-different-backend-p sym))) (push sym (if (eq (doom-package-backend sym) 'quelpa) quelpa-pkgs @@ -158,7 +168,10 @@ Used by `doom/packages-autoremove'." (doom-initialize-packages t) (let ((package-selected-packages (append (mapcar #'car doom-packages) doom-core-packages))) - (package--removable-packages))) + (append (package--removable-packages) + (cl-loop for pkg in package-selected-packages + if (doom-package-different-backend-p pkg) + collect pkg)))) ;;;###autoload (defun doom-get-missing-packages (&optional include-ignored-p) @@ -171,14 +184,15 @@ If INCLUDE-IGNORED-P is non-nil, includes missing packages that are ignored, i.e. they have an :ignore property. Used by `doom/packages-install'." - (cl-loop for pkgsym in (doom-get-packages) - unless - (let ((pkg (car pkgsym))) - (or (assq pkg package-alist) - (unless include-ignored-p (doom-package-prop pkg :ignore)) - (and (not (plist-get (assq pkg doom-packages) :pin)) - (assq pkg package--builtins)))) - collect pkgsym)) + (cl-loop for desc in (doom-get-packages) + for (name . plist) = desc + if (and (or include-ignored-p + (not (plist-get plist :ignore))) + (or (plist-get plist :pin) + (not (assq name package--builtins))) + (or (not (assq name package-alist)) + (doom-package-different-backend-p name))) + collect desc)) ;;;###autoload (defun doom*package-delete (desc &rest _) @@ -238,6 +252,8 @@ Used by `doom/packages-install'." example; the package name can be omitted)." (doom-initialize-packages) (when (package-installed-p name) + (when (doom-package-different-backend-p name) + (doom-delete-package name t)) (user-error "%s is already installed" name)) (let ((plist (or plist (cdr (assq name doom-packages)))) (inhibit-message (not doom-debug-mode)) @@ -314,14 +330,20 @@ package.el as appropriate." (y-or-n-p (format "%s packages will be installed:\n\n%s\n\nProceed?" (length packages) - (mapconcat (lambda (pkg) - (format "+ %s (%s)" - (car pkg) - (if (plist-get (cdr pkg) :recipe) - "QUELPA" - "ELPA"))) - (sort (cl-copy-list packages) #'doom--sort-alpha) - "\n"))))) + (mapconcat + (lambda (pkg) + (format "+ %s (%s)" + (car pkg) + (cond ((doom-package-different-backend-p (car pkg)) + (if (plist-get (cdr pkg) :recipe) + "ELPA -> QUELPA" + "QUELPA -> ELPA")) + ((plist-get (cdr pkg) :recipe) + "QUELPA") + (t + "ELPA")))) + (sort (cl-copy-list packages) #'doom--sort-alpha) + "\n"))))) (message! (yellow "Aborted!"))) (t @@ -396,12 +418,21 @@ package.el as appropriate." (y-or-n-p (format "%s packages will be deleted:\n\n%s\n\nProceed?" (length packages) - (mapconcat (lambda (sym) (format "+ %s (%s)" sym - (pcase (doom-package-backend sym) - ('quelpa "QUELPA") - ('elpa "ELPA")))) - (sort (cl-copy-list packages) #'string-lessp) - "\n"))))) + (mapconcat + (lambda (sym) + (format + "+ %s (%s)" + sym + (let ((backend (doom-package-backend sym))) + (if (doom-package-different-backend-p sym) + (if (eq backend 'quelpa) + "QUELPA->ELPA" + "ELPA->QUELPA") + (if (eq backend 'quelpa) + "QUELPA" + "ELPA"))))) + (sort (cl-copy-list packages) #'string-lessp) + "\n"))))) (message! (yellow "Aborted!"))) (t @@ -417,6 +448,7 @@ package.el as appropriate." (message! (bold (green "Finished!"))) (doom//reload-load-path))))) + ;;;###autoload (defalias 'doom/install-package #'package-install)