diff options
| author | Artur Malabarba | 2015-04-05 23:39:43 +0100 |
|---|---|---|
| committer | Artur Malabarba | 2015-04-06 11:19:04 +0100 |
| commit | 7471fc47b4bc78ed1a55e045ddb2d0b3eba19305 (patch) | |
| tree | 4f0e502a8ce8eadc5959f301057c656de55fb5b4 | |
| parent | 6701726b98261f862e4708aadb6d518b886cf8e2 (diff) | |
| download | emacs-7471fc47b4bc78ed1a55e045ddb2d0b3eba19305.tar.gz emacs-7471fc47b4bc78ed1a55e045ddb2d0b3eba19305.zip | |
emacs-lisp/package.el (package-menu-execute): Add async support
Most install/delete logic is now in
`package-menu--perform-transaction', and this function is called
asynchronously if `package-menu-async' is non-nil.
| -rw-r--r-- | lisp/ChangeLog | 2 | ||||
| -rw-r--r-- | lisp/emacs-lisp/package.el | 67 |
2 files changed, 40 insertions, 29 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 07e95429375..2fa005484a8 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -88,6 +88,8 @@ | |||
| 88 | (package-menu-execute): Use it to prompt the user about operations | 88 | (package-menu-execute): Use it to prompt the user about operations |
| 89 | to be executed. | 89 | to be executed. |
| 90 | (package-install): Add ASYNC and CALLBACK arguments. | 90 | (package-install): Add ASYNC and CALLBACK arguments. |
| 91 | (package-menu--perform-transaction): New function. | ||
| 92 | (package-menu-execute): Use it to install and delete packages. | ||
| 91 | 93 | ||
| 92 | 2015-04-05 Pete Williamson <petewil@chromium.org> (tiny-change) | 94 | 2015-04-05 Pete Williamson <petewil@chromium.org> (tiny-change) |
| 93 | 95 | ||
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 6d5d46c14bb..acfab92e7eb 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el | |||
| @@ -1368,8 +1368,8 @@ Once it's empty, run `package--post-download-archives-hook'." | |||
| 1368 | (remove entry package--downloads-in-progress)) | 1368 | (remove entry package--downloads-in-progress)) |
| 1369 | ;; If this was the last download, run the hook. | 1369 | ;; If this was the last download, run the hook. |
| 1370 | (unless package--downloads-in-progress | 1370 | (unless package--downloads-in-progress |
| 1371 | (package--build-compatibility-table) | ||
| 1372 | (package-read-all-archive-contents) | 1371 | (package-read-all-archive-contents) |
| 1372 | (package--build-compatibility-table) | ||
| 1373 | ;; We message before running the hook, so the hook can give | 1373 | ;; We message before running the hook, so the hook can give |
| 1374 | ;; messages as well. | 1374 | ;; messages as well. |
| 1375 | (message "Package refresh done") | 1375 | (message "Package refresh done") |
| @@ -2724,6 +2724,36 @@ not both." | |||
| 2724 | (mapconcat #'package-desc-full-name del ", "))))) | 2724 | (mapconcat #'package-desc-full-name del ", "))))) |
| 2725 | "? "))) | 2725 | "? "))) |
| 2726 | 2726 | ||
| 2727 | (defun package-menu--perform-transaction (install-list delete-list &optional async) | ||
| 2728 | "Install packages in INSTALL-LIST and delete DELETE-LIST. | ||
| 2729 | If ASYNC is non-nil, perform the installation downloads | ||
| 2730 | asynchronously." | ||
| 2731 | ;; While there are packages to install, call `package-install' on | ||
| 2732 | ;; the next one and defer deletion to the callback function. | ||
| 2733 | (if install-list | ||
| 2734 | (let* ((pkg (car install-list)) | ||
| 2735 | (rest (cdr install-list)) | ||
| 2736 | ;; Don't mark as selected if it's a new version of an | ||
| 2737 | ;; installed package. | ||
| 2738 | (dont-mark (and (not (package-installed-p pkg)) | ||
| 2739 | (package-installed-p | ||
| 2740 | (package-desc-name pkg))))) | ||
| 2741 | (package-install | ||
| 2742 | pkg dont-mark async | ||
| 2743 | (lambda () (package-menu--perform-transaction rest delete-list async)))) | ||
| 2744 | ;; Once there are no more packages to install, proceed to | ||
| 2745 | ;; deletion. | ||
| 2746 | (dolist (elt (package--sort-by-dependence delete-list)) | ||
| 2747 | (condition-case-unless-debug err | ||
| 2748 | (package-delete elt) | ||
| 2749 | (error (message (cadr err))))) | ||
| 2750 | (when package-selected-packages | ||
| 2751 | (when-let ((removable (package--removable-packages))) | ||
| 2752 | (message "These %d packages are no longer needed, type `M-x package-autoremove' to remove them (%s)" | ||
| 2753 | (length removable) | ||
| 2754 | (mapconcat #'symbol-name removable ", ")))) | ||
| 2755 | (package-menu--post-refresh))) | ||
| 2756 | |||
| 2727 | (defun package-menu-execute (&optional noquery) | 2757 | (defun package-menu-execute (&optional noquery) |
| 2728 | "Perform marked Package Menu actions. | 2758 | "Perform marked Package Menu actions. |
| 2729 | Packages marked for installation are downloaded and installed; | 2759 | Packages marked for installation are downloaded and installed; |
| @@ -2749,28 +2779,9 @@ Optional argument NOQUERY non-nil means do not ask the user to confirm." | |||
| 2749 | (user-error "No operations specified")) | 2779 | (user-error "No operations specified")) |
| 2750 | (when (or noquery | 2780 | (when (or noquery |
| 2751 | (package-menu--prompt-transaction-p install-list delete-list)) | 2781 | (package-menu--prompt-transaction-p install-list delete-list)) |
| 2752 | ;; Don't mark as selected if it's a new version of an installed | 2782 | ;; This calls `package-menu--generate' after everything's done. |
| 2753 | ;; package. | 2783 | (package-menu--perform-transaction |
| 2754 | (mapc (lambda (p) (package-install p (and (not (package-installed-p p)) | 2784 | install-list delete-list package-menu-async)))) |
| 2755 | (package-installed-p | ||
| 2756 | (package-desc-name p))))) | ||
| 2757 | install-list) | ||
| 2758 | ;; Delete packages. | ||
| 2759 | (dolist (elt (package--sort-by-dependence delete-list)) | ||
| 2760 | (condition-case-unless-debug err | ||
| 2761 | (package-delete elt) | ||
| 2762 | (error (message (cadr err))))) | ||
| 2763 | (when package-selected-packages | ||
| 2764 | (let ((removable (package--removable-packages))) | ||
| 2765 | (when (and removable | ||
| 2766 | (y-or-n-p | ||
| 2767 | (format "These %d packages are no longer needed, delete them (%s)? " | ||
| 2768 | (length removable) | ||
| 2769 | (mapconcat #'symbol-name removable ", ")))) | ||
| 2770 | ;; We know these are removable, so we can use force instead of sorting them. | ||
| 2771 | (mapc (lambda (p) (package-delete (cadr (assq p package-alist)) 'force 'nosave)) | ||
| 2772 | removable))))) | ||
| 2773 | (package-menu--generate t t))) | ||
| 2774 | 2785 | ||
| 2775 | (defun package-menu--version-predicate (A B) | 2786 | (defun package-menu--version-predicate (A B) |
| 2776 | (let ((vA (or (aref (cadr A) 1) '(0))) | 2787 | (let ((vA (or (aref (cadr A) 1) '(0))) |
| @@ -2843,9 +2854,8 @@ Store this list in `package-menu--new-package-list'." | |||
| 2843 | 2854 | ||
| 2844 | (defun package-menu--post-refresh () | 2855 | (defun package-menu--post-refresh () |
| 2845 | "Check for new packages, revert the *Packages* buffer, and check for upgrades. | 2856 | "Check for new packages, revert the *Packages* buffer, and check for upgrades. |
| 2846 | This function is called after `package-refresh-contents' is done. | 2857 | This function is called after `package-refresh-contents' and |
| 2847 | It goes in `package--post-download-archives-hook', so that it | 2858 | after `package-menu--perform-transaction'." |
| 2848 | works with async refresh as well." | ||
| 2849 | (package-menu--populate-new-package-list) | 2859 | (package-menu--populate-new-package-list) |
| 2850 | (let ((buf (get-buffer "*Packages*"))) | 2860 | (let ((buf (get-buffer "*Packages*"))) |
| 2851 | (when (buffer-live-p buf) | 2861 | (when (buffer-live-p buf) |
| @@ -2855,9 +2865,8 @@ works with async refresh as well." | |||
| 2855 | 2865 | ||
| 2856 | (defcustom package-menu-async t | 2866 | (defcustom package-menu-async t |
| 2857 | "If non-nil, package-menu will use async operations when possible. | 2867 | "If non-nil, package-menu will use async operations when possible. |
| 2858 | Currently, only the refreshing of archive contents supports | 2868 | This includes refreshing archive contents as well as installing |
| 2859 | asynchronous operations. Package transactions are still done | 2869 | packages." |
| 2860 | synchronously." | ||
| 2861 | :type 'boolean | 2870 | :type 'boolean |
| 2862 | :group 'package) | 2871 | :group 'package) |
| 2863 | 2872 | ||