diff --git a/core/autoload/packages.el b/core/autoload/packages.el index e096a6d05..f808222f8 100644 --- a/core/autoload/packages.el +++ b/core/autoload/packages.el @@ -70,6 +70,18 @@ list of the package." (version-list-< old-version new-version)) (list name old-version new-version))))) +;;;###autoload +(defun doom-package-ignored-p (name) + "Return t if NAME (a package symbol) has an :ignore property." + (doom-initialize-packages) + (plist-get (cdr (assq name doom-packages)) :ignore)) + +;;;###autoload +(defun doom-package-frozen-p (name) + "Return t if NAME (a package symbol) has an :frozen property." + (doom-initialize-packages) + (plist-get (cdr (assq name doom-packages)) :freeze)) + ;;;###autoload (defun doom-get-packages (&optional backend) "Retrieves a list of explicitly installed packages (i.e. non-dependencies). @@ -103,12 +115,18 @@ Be careful not to use it in a loop." (package--get-deps name only)) ;;;###autoload -(defun doom-get-outdated-packages () +(defun doom-get-outdated-packages (&optional include-frozen-p) "Return a list of packages that are out of date. Each element is a list, containing (PACKAGE-SYMBOL OLD-VERSION-LIST NEW-VERSION-LIST). +If INCLUDE-FROZEN-P is non-nil, check frozen packages as well. + Used by `doom/packages-update'." - (delq nil (mapcar #'doom-package-outdated-p (mapcar #'car (doom-get-packages))))) + (let ((pkgs (mapcar #'car (doom-get-packages)))) + (delq nil + (mapcar #'doom-package-outdated-p + (if include-frozen-p pkgs + (cl-remove-if #'doom-package-frozen-p pkgs)))))) ;;;###autoload (defun doom-get-orphaned-packages () @@ -119,21 +137,25 @@ Used by `doom/packages-autoremove'." (doom-initialize-packages t) (let ((package-selected-packages (append (mapcar #'car doom-packages) doom-core-packages))) - (cl-set-difference (package--removable-packages) - doom-protected-packages))) + (package--removable-packages))) ;;;###autoload -(defun doom-get-missing-packages () +(defun doom-get-missing-packages (&optional include-ignored-p) "Return a list of requested packages that aren't installed or built-in, but are enabled (with a `package!' directive). Each element is a list whose CAR is the package symbol, and whose CDR is a plist taken from that package's `package!' declaration. +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-remove-if (lambda (pkgsym) - (or (assq (car pkgsym) package-alist) - (and (not (plist-get (assq (car pkgsym) doom-packages) :pin)) - (assq (car pkgsym) package--builtins)))) + (let ((pkg (car pkgsym))) + (or (assq pkg package-alist) + (unless include-ignored-p (doom-package-ignored-p pkg)) + (and (not (plist-get (assq pkg doom-packages) :pin)) + (assq pkg package--builtins))))) (doom-get-packages))) ;;;###autoload diff --git a/core/core-packages.el b/core/core-packages.el index 9db7c87ee..9ff9db98b 100644 --- a/core/core-packages.el +++ b/core/core-packages.el @@ -56,9 +56,6 @@ package's name as a symbol, and whose CDR is the plist supplied to its "A list of packages that must be installed (and will be auto-installed if missing) and shouldn't be deleted.") -(defvar doom-protected-packages nil - "A list of packages that shouldn't be deleted by `doom/packages-autoremove'.") - (defvar doom-init-time nil "The time it took, in seconds, for DOOM Emacs to initialize.") @@ -359,6 +356,8 @@ Accepts the following properties: from external sources. :pin ARCHIVE-NAME Instructs ELPA to only look for this package in ARCHIVE-NAME. e.g. \"org\". Ignored if RECIPE is present. + :ignore t Do not install this package. + :freeze t Do not update this package. This macro serves a purely declarative purpose, and are used to fill `doom-packages', so that functions like `doom/packages-install' can operate on @@ -380,6 +379,7 @@ them." :test #'eq :key #'car)) (when ,(and old-plist t) (assq-delete-all ',name doom-packages)) + ;; :ignore and :freeze are handled upstream (push ',(cons name plist) doom-packages)))) (defmacro depends-on! (module submodule)