From c184e85ea2adfc5b63f1fe55a6fa2eaaacbda97b Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 3 Feb 2015 13:43:10 +0000 Subject: [PATCH] emacs-lisp/package.el (package--user-selected-p): New function. Populates `package-selected-packages' if necessary, and then checks if symbol PKG is contained in it. --- lisp/ChangeLog | 12 +++++ lisp/emacs-lisp/package.el | 105 +++++++++++++++++++++++-------------- 2 files changed, 77 insertions(+), 40 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 61e05705c41..d3850310dc5 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -2,6 +2,18 @@ * emacs-lisp/package.el (package-delete): Document NOSAVE. (package--get-deps): delete-dups when ONLY is nil. + (package-autoremove): Warn the user if `package-selected-packages' + is empty. + + (package--user-selected-p): New function. + (package-delete, package-install, package-install-from-buffer): + Use it + (package-selected-packages): Mention it. + + (package-initialize): Don't populate `package-selected-packages'. + (package-install-user-selected-packages, package-autoremove): + Special handling for empty `package-selected-packages'. + (package-install): Fix when PKG is a package-desc. 2015-02-03 Thierry Volpiatto diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index ade36d7c7d3..bda88b659d1 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -340,7 +340,11 @@ when installing a new package. This variable will be used by `package-autoremove' to decide which packages are no more needed. You can use it to (re)install packages on other machines -by running `package-user-selected-packages-install'." +by running `package-user-selected-packages-install'. + +To check if a package is contained in this list here, use +`package--user-selected-p', as it may populate the variable with +a sane initial value." :group 'package :type '(repeat symbol)) @@ -1189,6 +1193,17 @@ number." nil)) alist))) +(defun package--user-selected-p (pkg) + "Return non-nil if PKG is a package was installed by the user. +PKG is a package name. +This looks into `package-selected-packages', populating it first +if it is still empty." + (unless (consp package-selected-packages) + (customize-save-variable + 'package-selected-packages + (setq package-selected-packages (package--find-non-dependencies)))) + (memq pkg package-selected-packages)) + (defun package-download-transaction (packages) "Download and install all the packages in PACKAGES. PACKAGES should be a list of package-desc. @@ -1222,9 +1237,12 @@ to `package-selected-packages'." package-archive-contents)) nil t)) t))) - (when (and mark-selected (not (memq pkg package-selected-packages))) - (customize-save-variable 'package-selected-packages - (cons pkg package-selected-packages))) + (let ((name (if (package-desc-p pkg) + (package-desc-name pkg) + pkg))) + (when (and mark-selected (not (package--user-selected-p name))) + (customize-save-variable 'package-selected-packages + (cons name package-selected-packages)))) (package-download-transaction (if (package-desc-p pkg) (package-compute-transaction (list pkg) @@ -1239,8 +1257,7 @@ to `package-selected-packages'." "Reinstall package: " (mapcar #'symbol-name (mapcar #'car package-alist)))))) - (package-delete (cadr (assq pkg package-alist)) 'force - (memq pkg package-selected-packages)) + (package-delete (cadr (assq pkg package-alist)) 'force 'nosave) (package-install pkg)) (defun package-strip-rcs-id (str) @@ -1402,10 +1419,9 @@ Downloads and installs required packages as needed." (package-download-transaction transaction)) ;; Install the package itself. (package-unpack pkg-desc) - (unless (memq name package-selected-packages) - (push name package-selected-packages) + (unless (package--user-selected-p name) (customize-save-variable 'package-selected-packages - package-selected-packages)) + (cons name package-selected-packages))) pkg-desc)) ;;;###autoload @@ -1443,17 +1459,22 @@ The file can either be a tar file or an Emacs Lisp file." "Ensure packages in `package-selected-packages' are installed. If some packages are not installed propose to install them." (interactive) - (cl-loop for p in package-selected-packages - unless (package-installed-p p) - collect p into lst - finally - (if lst - (when (y-or-n-p - (format "%s packages will be installed:\n%s, proceed?" - (length lst) - (mapconcat #'symbol-name lst ", "))) - (mapc #'package-install lst)) - (message "All your packages are already installed")))) + ;; We don't need to populate `package-selected-packages' before + ;; using here, because the outcome is the same either way (nothing + ;; gets installed). + (if (not package-selected-packages) + (message "`package-selected-packages' is empty, nothing to install") + (cl-loop for p in package-selected-packages + unless (package-installed-p p) + collect p into lst + finally + (if lst + (when (y-or-n-p + (format "%s packages will be installed:\n%s, proceed?" + (length lst) + (mapconcat #'symbol-name lst ", "))) + (mapc #'package-install lst)) + (message "All your packages are already installed"))))) (defun package--used-elsewhere-p (pkg-desc &optional pkg-list) "Non-nil if PKG-DESC is a dependency of a package in PKG-LIST. @@ -1509,8 +1530,8 @@ If NOSAVE is non-nil, the package is not removed from (unless (cdr pkgs) (setq package-alist (delq pkgs package-alist)))) ;; Update package-selected-packages. - (when (and (memq name package-selected-packages) - (null nosave)) + (when (and (null nosave) + (package--user-selected-p name)) (customize-save-variable 'package-selected-packages (remove name package-selected-packages))) (message "Package `%s' deleted." (package-desc-full-name pkg-desc)))))) @@ -1523,21 +1544,28 @@ Packages that are no more needed by other packages in `package-selected-packages' and their dependencies will be deleted." (interactive) - (let ((needed (cl-loop for p in package-selected-packages - if (assq p package-alist) - append (package--get-deps p)))) - (cl-loop for p in (mapcar #'car package-alist) - unless (or (memq p needed) - (memq p package-selected-packages)) - collect p into lst - finally (if lst - (when (y-or-n-p (format "%s packages will be deleted:\n%s, proceed? " - (length lst) - (mapconcat #'symbol-name lst ", "))) - (mapc (lambda (p) - (package-delete (cadr (assq p package-alist)) t)) - lst)) - (message "Nothing to autoremove"))))) + ;; If `package-selected-packages' is nil, it would make no sense to + ;; try to populate it here, because then `package-autoremove' will + ;; do absolutely nothing. + (when (or package-selected-packages + (yes-or-no-p + "`package-selected-packages' is empty! Really remove ALL packages? ")) + (let ((needed (cl-loop for p in package-selected-packages + if (assq p package-alist) + ;; `p' and its dependencies are needed. + append (cons p (package--get-deps p))))) + (cl-loop for p in (mapcar #'car package-alist) + unless (memq p needed) + collect p into lst + finally (if lst + (when (y-or-n-p + (format "%s packages will be deleted:\n%s, proceed? " + (length lst) + (mapconcat #'symbol-name lst ", "))) + (mapc (lambda (p) + (package-delete (cadr (assq p package-alist)) t)) + lst)) + (message "Nothing to autoremove")))))) (defun package-archive-base (desc) "Return the archive containing the package NAME." @@ -1663,9 +1691,6 @@ If optional arg NO-ACTIVATE is non-nil, don't activate packages." (unless no-activate (dolist (elt package-alist) (package-activate (car elt)))) - (when (and package-alist (not package-selected-packages)) - (customize-save-variable 'package-selected-packages - (package--find-non-dependencies))) (setq package--initialized t)) -- 2.39.2