Add option to select packages for update

This commit changes the yes-or-no-p to a read-answer with three options y, s and
n (for yes, some and no. This of course could be a, s, c for 'all',
'some/select' and 'cancel', but I decided to keep yes no as users are already
familiar with the y and n).

Finally the user can select packages by answer for each package in the list a
yes-or-no-p (pressing y or n, if you upgrade regularly the list usually is not
too long. It is anyway better than having only the options all or none).

The `nonc` construction is just a non cl alternative to cl-remove-if (I've added
the comment with the explanation).
This commit is contained in:
Daniel Nicolai 2021-10-01 23:47:28 +02:00 committed by Maxi Wolff
parent 76841d87fc
commit cac0105553
2 changed files with 55 additions and 42 deletions

View File

@ -671,6 +671,7 @@ Other:
keymaps and top-level keymap, under prefix ~SPC t k~ (thanks to Daniel Nicolai)
- Add =describe-ex-command= on ~SPC h d x~ (thanks to Daniel Nicolai)
- Support packing elisp to *.elc and *.el.gz (thanks to Lin Sun)
- Add option to select and update only some packages (thanks to Daniel Nicolai)
- Fixes:
- Avoid non-idempotent use of push in init code (thanks to Miciah Masters)
- Moved Spacemacs startup progress bar to =core-progress-bar.el=, removed

View File

@ -2159,51 +2159,63 @@ to update."
"%s (won't be updated because package is frozen)\n"
"%s\n") x) t))
(sort (mapcar 'symbol-name update-packages) 'string<))
(if (and (not no-confirmation)
(not (yes-or-no-p
(format "Do you want to update %s package(s)? "
upgrade-count))))
(spacemacs-buffer/append "Packages update has been cancelled.\n" t)
(when (not no-confirmation)
(let ((answer (let ((read-answer-short t))
(read-answer (format "Do you want to update %s package(s)? "
upgrade-count)
'(("yes" ?y "upgrade all listed packages")
("some" ?s "select packages to upgrade")
("no" ?n "don't upgrade packages"))))))
(if (string= answer "no")
(spacemacs-buffer/append "Packages update has been cancelled.\n" t)
;; backup the package directory and construct an alist
;; variable to be cached for easy update and rollback
(spacemacs-buffer/append
"--> performing backup of package(s) to update...\n" t)
(spacemacs//redisplay)
(dolist (pkg update-packages)
(unless (memq pkg dotspacemacs-frozen-packages)
(let* ((src-dir (configuration-layer//get-package-directory pkg))
(dest-dir (expand-file-name
(concat rollback-dir
(file-name-as-directory
(file-name-nondirectory src-dir))))))
(copy-directory src-dir dest-dir 'keeptime 'create 'copy-content)
(push (cons pkg (file-name-nondirectory src-dir))
update-packages-alist))))
(spacemacs/dump-vars-to-file
'(update-packages-alist)
(expand-file-name (concat rollback-dir
configuration-layer-rollback-info)))
(dolist (pkg update-packages)
(unless (memq pkg dotspacemacs-frozen-packages)
(setq upgraded-count (1+ upgraded-count))
(spacemacs-buffer/replace-last-line
(format "--> preparing update of package %s... [%s/%s]"
pkg upgraded-count upgrade-count) t)
(when (string= answer "some")
(setq update-packages
;; 'apply nconc on list of lists' is equivalent to 'cl-remove-if nil'
(apply #'nconc (mapcar (lambda (pkg)
(when (yes-or-no-p (format "Update package '%s'? " pkg))
(list pkg)))
update-packages))))
(setq upgrade-count (length update-packages))
(spacemacs-buffer/append
"--> performing backup of package(s) to update...\n" t)
(spacemacs//redisplay)
(configuration-layer//package-delete pkg)))
(spacemacs-buffer/append
(format "\n--> %s package(s) to be updated.\n" upgraded-count))
(spacemacs-buffer/append
(format "\nRestart Emacs to install the updated packages. %s\n"
(if (member 'restart-emacs update-packages)
(concat "\n(SPC q r) won't work this time, because the"
"\nrestart-emacs package is being updated.")
"(SPC q r)")))
(configuration-layer//cleanup-rollback-directory)
(spacemacs//redisplay)))
(when (eq upgrade-count 0)
(spacemacs-buffer/append "--> All packages are up to date.\n")
(spacemacs//redisplay))))
(dolist (pkg update-packages)
(unless (memq pkg dotspacemacs-frozen-packages)
(let* ((src-dir (configuration-layer//get-package-directory pkg))
(dest-dir (expand-file-name
(concat rollback-dir
(file-name-as-directory
(file-name-nondirectory src-dir))))))
(copy-directory src-dir dest-dir 'keeptime 'create 'copy-content)
(push (cons pkg (file-name-nondirectory src-dir))
update-packages-alist))))
(spacemacs/dump-vars-to-file
'(update-packages-alist)
(expand-file-name (concat rollback-dir
configuration-layer-rollback-info)))
(dolist (pkg update-packages)
(unless (memq pkg dotspacemacs-frozen-packages)
(setq upgraded-count (1+ upgraded-count))
(spacemacs-buffer/replace-last-line
(format "--> preparing update of package %s... [%s/%s]"
pkg upgraded-count upgrade-count) t)
(spacemacs//redisplay)
(configuration-layer//package-delete pkg)))
(spacemacs-buffer/append
(format "\n--> %s package(s) to be updated.\n" upgraded-count))
(spacemacs-buffer/append
(format "\nRestart Emacs to install the updated packages. %s\n"
(if (member 'restart-emacs update-packages)
(concat "\n(SPC q r) won't work this time, because the"
"\nrestart-emacs package is being updated.")
"(SPC q r)")))
(configuration-layer//cleanup-rollback-directory)
(spacemacs//redisplay)))))
(when (eq upgrade-count 0)
(spacemacs-buffer/append "--> All packages are up to date.\n")
(spacemacs//redisplay))))
(defun configuration-layer//ido-candidate-rollback-slot ()
"Return a list of candidates to select a rollback slot."