16

I am frequently prompted when updating my current packages to run package-autoremove which claims to remove outdated or unnecessary packages. However it always seems to remove (along with those outdated packages) two packages which I do use (namely aurora-theme, my current theme of choice and dired+).

I'm afraid I'm something of a novice when it comes to Emacs-Lisp and I was just wondering if there was a way I could stop package autoremove deleting these packages so I didn't need to keep reinstalling them.

Drew
  • 77,472
  • 10
  • 114
  • 243
tannart
  • 263
  • 2
  • 6

1 Answers1

7

The source is here: https://github.com/emacs-mirror/emacs/blob/master/lisp/emacs-lisp/package.el#L2113.

It deletes all packages that is not in package-selected-packages nor a dependency.

(defun package-autoremove ()
"Remove packages that are no more needed.
        Packages that are no more needed by other packages in
        `package-selected-packages' and their dependencies
        will be deleted."
(interactive)
;; 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
            (format-message
            "`package-selected-packages' is empty! Really remove ALL packages? ")))
    (let ((removable (package--removable-packages)))
    (if removable
        (when (y-or-n-p
                (format "%s packages will be deleted:\n%s, proceed? "
                        (length removable)
                        (mapconcat #'symbol-name removable ", ")))
            (mapc (lambda (p)
                    (package-delete (cadr (assq p package-alist)) t))
                removable))
        (message "Nothing to autoremove")))))

(defun package--removable-packages ()
  "Return a list of names of packages no longer needed.
These are packages which are neither contained in
`package-selected-packages' nor a dependency of one that is."
  (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)))
jiegec
  • 136
  • 5
  • 1
    So this code means if a package name is added to package-selected-packages, it won't be autoremoved. – zck Nov 20 '15 at 13:35
  • @zck Yes. The package--removable-packages did that. – jiegec Nov 20 '15 at 13:38
  • Also worth noting that package-selected-packages is updated automatically when you install and remove packages. You generally don't need to modify it directly. If you see things being auto-removed they are likely packages that were pulled in as dependencies of something you installed and then later removed. In addition to supporting auto-remove, this variable can be used when you copy your emacs config to a new machine and want to install everything in your selected packages list, using package-install-selected-packages. – glucas Nov 20 '15 at 14:38
  • 2
    @jiegec My point, poorly written, was that the solution to the user's problem ("how do I prevent packages from being autoremoved") is "add the packages to package-selected-packages. – zck Nov 20 '15 at 16:45
  • @zck Yes. You are right – jiegec Nov 20 '15 at 23:05