- (goto-char (point-min))
- (while (not (eobp))
- (let ((cmd (char-after))
- (pkg-name (package-menu-get-package))
- (pkg-vers (package-menu-get-version))
- (pkg-status (package-menu-get-status)))
- (cond
- ((eq cmd ?D)
- (when (and (string= pkg-status "installed")
- (string= pkg-name "package"))
- ;; FIXME: actually, we could be tricky and remove all info.
- ;; But that is drastic and the user can do that instead.
- (error "Can't delete most recent version of `package'"))
- ;; Ask for confirmation here? Maybe if package status is ""?
- ;; Or if any lisp from package is actually loaded?
- (message "Deleting %s-%s..." pkg-name pkg-vers)
- (package-delete pkg-name pkg-vers)
- (message "Deleting %s-%s... done" pkg-name pkg-vers))
- ((eq cmd ?I)
- (package-install (intern pkg-name)))))
- (forward-line))
- (package-menu-revert))
+ (let (install-list delete-list cmd)
+ (save-excursion
+ (goto-char (point-min))
+ (while (not (eobp))
+ (setq cmd (char-after))
+ (cond
+ ((eq cmd ?\s) t)
+ ((eq cmd ?D)
+ (push (cons (package-menu-get-package)
+ (package-menu-get-version))
+ delete-list))
+ ((eq cmd ?I)
+ (push (package-menu-get-package) install-list)))
+ (forward-line)))
+ ;; Delete packages, prompting if necessary.
+ (when delete-list
+ (if (yes-or-no-p
+ (if (= (length delete-list) 1)
+ (format "Delete package `%s-%s'? "
+ (caar delete-list)
+ (cdr (car delete-list)))
+ (format "Delete these %d packages (%s)? "
+ (length delete-list)
+ (mapconcat (lambda (elt)
+ (concat (car elt) "-" (cdr elt)))
+ delete-list
+ ", "))))
+ (dolist (elt delete-list)
+ (condition-case err
+ (package-delete (car elt) (cdr elt))
+ (error (message (cadr err)))))
+ (error "Aborted")))
+ (when install-list
+ (if (yes-or-no-p
+ (if (= (length install-list) 1)
+ (format "Install package `%s'? " (car install-list))
+ (format "Install these %d packages (%s)? "
+ (length install-list)
+ (mapconcat 'identity install-list ", "))))
+ (dolist (elt install-list)
+ (package-install (intern elt)))))
+ ;; If we deleted anything, regenerate `package-alist'. This is done
+ ;; automatically if we installed a package.
+ (and delete-list (null install-list)
+ (package-initialize))
+ (if (or delete-list install-list)
+ (package-menu-revert)
+ (message "No operations specified."))))