diff options
| author | Artur Malabarba | 2015-02-03 17:51:39 -0200 |
|---|---|---|
| committer | Artur Malabarba | 2015-02-03 17:51:39 -0200 |
| commit | 2a4a5069a6a0dba8888d72e60b66a3df5ed5a8cb (patch) | |
| tree | ccb750252fbfd10fe7403c846d049bf846d527dd | |
| parent | 504fada7e7502b9052076c20f16f55d7e9bd3c58 (diff) | |
| download | emacs-2a4a5069a6a0dba8888d72e60b66a3df5ed5a8cb.tar.gz emacs-2a4a5069a6a0dba8888d72e60b66a3df5ed5a8cb.zip | |
emacs-lisp/package.el (package-menu-execute): Offer to remove packages.
| -rw-r--r-- | lisp/ChangeLog | 4 | ||||
| -rw-r--r-- | lisp/emacs-lisp/package.el | 53 |
2 files changed, 38 insertions, 19 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c834d7cc168..38d41b27ef4 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -21,6 +21,10 @@ | |||
| 21 | (package-menu-mark-delete, package-menu--find-upgrades) | 21 | (package-menu-mark-delete, package-menu--find-upgrades) |
| 22 | (package-menu--status-predicate, describe-package-1): Use it | 22 | (package-menu--status-predicate, describe-package-1): Use it |
| 23 | 23 | ||
| 24 | (package--removable-packages): New function. | ||
| 25 | (package-autoremove): Use it. | ||
| 26 | (package-menu-execute): Offer to remove unneeded packages. | ||
| 27 | |||
| 24 | 2015-02-03 Thierry Volpiatto <thierry.volpiatto@gmail.com> | 28 | 2015-02-03 Thierry Volpiatto <thierry.volpiatto@gmail.com> |
| 25 | 29 | ||
| 26 | * emacs-lisp/package.el (package-reinstall): Don't change package's selected status. | 30 | * emacs-lisp/package.el (package-reinstall): Don't change package's selected status. |
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 298604e9892..d013fd4a329 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el | |||
| @@ -1536,6 +1536,18 @@ If NOSAVE is non-nil, the package is not removed from | |||
| 1536 | 'package-selected-packages (remove name package-selected-packages))) | 1536 | 'package-selected-packages (remove name package-selected-packages))) |
| 1537 | (message "Package `%s' deleted." (package-desc-full-name pkg-desc)))))) | 1537 | (message "Package `%s' deleted." (package-desc-full-name pkg-desc)))))) |
| 1538 | 1538 | ||
| 1539 | (defun package--removable-packages () | ||
| 1540 | "Return a list of names of packages no longer needed. | ||
| 1541 | These are packages which are neither contained in | ||
| 1542 | `package-selected-packages' nor a dependency of one that is." | ||
| 1543 | (let ((needed (cl-loop for p in package-selected-packages | ||
| 1544 | if (assq p package-alist) | ||
| 1545 | ;; `p' and its dependencies are needed. | ||
| 1546 | append (cons p (package--get-deps p))))) | ||
| 1547 | (cl-loop for p in (mapcar #'car package-alist) | ||
| 1548 | unless (memq p needed) | ||
| 1549 | collect p))) | ||
| 1550 | |||
| 1539 | ;;;###autoload | 1551 | ;;;###autoload |
| 1540 | (defun package-autoremove () | 1552 | (defun package-autoremove () |
| 1541 | "Remove packages that are no more needed. | 1553 | "Remove packages that are no more needed. |
| @@ -1550,22 +1562,16 @@ will be deleted." | |||
| 1550 | (when (or package-selected-packages | 1562 | (when (or package-selected-packages |
| 1551 | (yes-or-no-p | 1563 | (yes-or-no-p |
| 1552 | "`package-selected-packages' is empty! Really remove ALL packages? ")) | 1564 | "`package-selected-packages' is empty! Really remove ALL packages? ")) |
| 1553 | (let ((needed (cl-loop for p in package-selected-packages | 1565 | (let ((removable (package--removable-packages))) |
| 1554 | if (assq p package-alist) | 1566 | (if removable |
| 1555 | ;; `p' and its dependencies are needed. | 1567 | (when (y-or-n-p |
| 1556 | append (cons p (package--get-deps p))))) | 1568 | (format "%s packages will be deleted:\n%s, proceed? " |
| 1557 | (cl-loop for p in (mapcar #'car package-alist) | 1569 | (length removable) |
| 1558 | unless (memq p needed) | 1570 | (mapconcat #'symbol-name removable ", "))) |
| 1559 | collect p into lst | 1571 | (mapc (lambda (p) |
| 1560 | finally (if lst | 1572 | (package-delete (cadr (assq p package-alist)) t)) |
| 1561 | (when (y-or-n-p | 1573 | removable) |
| 1562 | (format "%s packages will be deleted:\n%s, proceed? " | 1574 | (message "Nothing to autoremove")))))) |
| 1563 | (length lst) | ||
| 1564 | (mapconcat #'symbol-name lst ", "))) | ||
| 1565 | (mapc (lambda (p) | ||
| 1566 | (package-delete (cadr (assq p package-alist)) t)) | ||
| 1567 | lst)) | ||
| 1568 | (message "Nothing to autoremove")))))) | ||
| 1569 | 1575 | ||
| 1570 | (defun package-archive-base (desc) | 1576 | (defun package-archive-base (desc) |
| 1571 | "Return the archive containing the package NAME." | 1577 | "Return the archive containing the package NAME." |
| @@ -2377,9 +2383,18 @@ Optional argument NOQUERY non-nil means do not ask the user to confirm." | |||
| 2377 | (package-delete elt) | 2383 | (package-delete elt) |
| 2378 | (error (message (cadr err))))) | 2384 | (error (message (cadr err))))) |
| 2379 | (error "Aborted"))) | 2385 | (error "Aborted"))) |
| 2380 | (if (or delete-list install-list) | 2386 | (if (not (or delete-list install-list)) |
| 2381 | (package-menu--generate t t) | 2387 | (message "No operations specified.") |
| 2382 | (message "No operations specified.")))) | 2388 | (when package-selected-packages |
| 2389 | (let ((removable (package--removable-packages))) | ||
| 2390 | (when (and removable | ||
| 2391 | (y-or-n-p | ||
| 2392 | (format "These %d packages are no longer needed, delete them (%s)? " | ||
| 2393 | (length removable) | ||
| 2394 | (mapconcat #'symbol-name removable ", ")))) | ||
| 2395 | (mapc (lambda (p) (package-delete (cadr (assq p package-alist)))) | ||
| 2396 | removable)))) | ||
| 2397 | (package-menu--generate t t)))) | ||
| 2383 | 2398 | ||
| 2384 | (defun package-menu--version-predicate (A B) | 2399 | (defun package-menu--version-predicate (A B) |
| 2385 | (let ((vA (or (aref (cadr A) 1) '(0))) | 2400 | (let ((vA (or (aref (cadr A) 1) '(0))) |