aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtur Malabarba2015-04-01 11:09:00 +0100
committerArtur Malabarba2015-04-01 11:09:00 +0100
commitaa33f4a100e4539aaa04a8e1647d926f972c2673 (patch)
tree281e6ecceee9ecf0bbd336fef7e1690408bf811a
parentba7a1a7a4eb64dd391d2e866c82cadfcc00d364d (diff)
downloademacs-aa33f4a100e4539aaa04a8e1647d926f972c2673.tar.gz
emacs-aa33f4a100e4539aaa04a8e1647d926f972c2673.zip
* emacs-lisp/package.el: Make package-menu asynchronous.
(package-menu-async): New variable. Controls whether `list-packages' is asynchronous. (list-packages): Now asynchronous by default. (package-menu--new-package-list): Always buffer-local. (package-menu--post-refresh) (package-menu--find-and-notify-upgrades) (package-menu--populate-new-package-list): New functions.
-rw-r--r--lisp/ChangeLog9
-rw-r--r--lisp/emacs-lisp/package.el93
2 files changed, 71 insertions, 31 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index da3cd513ca2..b35c78da09e 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -10,6 +10,15 @@
10 (package--post-download-archives-hook): New variable. Hook run 10 (package--post-download-archives-hook): New variable. Hook run
11 after every refresh. 11 after every refresh.
12 12
13 * emacs-lisp/package.el: Make package-menu asynchronous.
14 (package-menu-async): New variable. Controls whether
15 `list-packages' is asynchronous.
16 (list-packages): Now asynchronous by default.
17 (package-menu--new-package-list): Always buffer-local.
18 (package-menu--post-refresh)
19 (package-menu--find-and-notify-upgrades)
20 (package-menu--populate-new-package-list): New functions.
21
132015-03-31 Simen Heggestøyl <simenheg@gmail.com> 222015-03-31 Simen Heggestøyl <simenheg@gmail.com>
14 23
15 * textmodes/css-mode.el (css-mode): Derive from `prog-mode'. 24 * textmodes/css-mode.el (css-mode): Derive from `prog-mode'.
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 89d92464119..490fb45a98f 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -2241,7 +2241,7 @@ will be deleted."
2241 map) 2241 map)
2242 "Local keymap for `package-menu-mode' buffers.") 2242 "Local keymap for `package-menu-mode' buffers.")
2243 2243
2244(defvar package-menu--new-package-list nil 2244(defvar-local package-menu--new-package-list nil
2245 "List of newly-available packages since `list-packages' was last called.") 2245 "List of newly-available packages since `list-packages' was last called.")
2246 2246
2247(define-derived-mode package-menu-mode tabulated-list-mode "Package Menu" 2247(define-derived-mode package-menu-mode tabulated-list-mode "Package Menu"
@@ -2749,6 +2749,49 @@ Optional argument NOQUERY non-nil means do not ask the user to confirm."
2749 (string< (or (package-desc-archive (car A)) "") 2749 (string< (or (package-desc-archive (car A)) "")
2750 (or (package-desc-archive (car B)) ""))) 2750 (or (package-desc-archive (car B)) "")))
2751 2751
2752(defvar-local package-menu--old-archive-contents nil
2753 "`package-archive-contents' before the latest refresh.")
2754
2755(defun package-menu--populate-new-package-list ()
2756 "Decide which packages are new in `package-archives-contents'.
2757Store this list in `package-menu--new-package-list'."
2758 ;; Find which packages are new.
2759 (when package-menu--old-archive-contents
2760 (dolist (elt package-archive-contents)
2761 (unless (assq (car elt) package-menu--old-archive-contents)
2762 (push (car elt) package-menu--new-package-list)))
2763 (setq package-menu--old-archive-contents nil)))
2764
2765(defun package-menu--find-and-notify-upgrades ()
2766 "Notify the user of upgradeable packages."
2767 (when-let ((upgrades (package-menu--find-upgrades)))
2768 (message "%d package%s can be upgraded; type `%s' to mark %s for upgrading."
2769 (length upgrades)
2770 (if (= (length upgrades) 1) "" "s")
2771 (substitute-command-keys "\\[package-menu-mark-upgrades]")
2772 (if (= (length upgrades) 1) "it" "them"))))
2773
2774(defun package-menu--post-refresh ()
2775 "Function to be called after `package-refresh-contents' is done.
2776Checks for new packages, reverts the *Packages* buffer, and
2777checks for upgrades.
2778This goes in `package--post-download-archives-hook', so that it
2779works with async refresh as well."
2780 (package-menu--populate-new-package-list)
2781 (let ((buf (get-buffer "*Packages*")))
2782 (when (buffer-live-p buf)
2783 (with-current-buffer buf
2784 (revert-buffer nil 'noconfirm))))
2785 (package-menu--find-and-notify-upgrades))
2786
2787(defcustom package-menu-async t
2788 "If non-nil, package-menu will use async operations when possible.
2789Currently, only the refreshing of archive contents supports
2790asynchronous operations. Package transactions are still done
2791synchronously."
2792 :type 'boolean
2793 :group 'package)
2794
2752;;;###autoload 2795;;;###autoload
2753(defun list-packages (&optional no-fetch) 2796(defun list-packages (&optional no-fetch)
2754 "Display a list of packages. 2797 "Display a list of packages.
@@ -2760,36 +2803,24 @@ The list is displayed in a buffer named `*Packages*'."
2760 ;; Initialize the package system if necessary. 2803 ;; Initialize the package system if necessary.
2761 (unless package--initialized 2804 (unless package--initialized
2762 (package-initialize t)) 2805 (package-initialize t))
2763 (let (old-archives new-packages) 2806 ;; Integrate the package-menu with updating the archives.
2764 (unless no-fetch 2807 (add-hook 'package--post-download-archives-hook
2765 ;; Read the locally-cached archive-contents. 2808 #'package-menu--post-refresh)
2766 (package-read-all-archive-contents) 2809
2767 (setq old-archives package-archive-contents) 2810 (unless no-fetch
2768 ;; Fetch the remote list of packages. 2811 (setq package-menu--old-archive-contents package-archive-contents)
2769 (package-refresh-contents) 2812 (setq package-menu--new-package-list nil)
2770 ;; Find which packages are new. 2813 ;; Fetch the remote list of packages.
2771 (dolist (elt package-archive-contents) 2814 (package-refresh-contents package-menu-async))
2772 (unless (assq (car elt) old-archives) 2815
2773 (push (car elt) new-packages)))) 2816 ;; Generate the Package Menu.
2774 2817 (let ((buf (get-buffer-create "*Packages*")))
2775 ;; Generate the Package Menu. 2818 (with-current-buffer buf
2776 (let ((buf (get-buffer-create "*Packages*"))) 2819 (package-menu-mode)
2777 (with-current-buffer buf 2820 (package-menu--generate nil t))
2778 (package-menu-mode) 2821 ;; The package menu buffer has keybindings. If the user types
2779 (set (make-local-variable 'package-menu--new-package-list) 2822 ;; `M-x list-packages', that suggests it should become current.
2780 new-packages) 2823 (switch-to-buffer buf)))
2781 (package-menu--generate nil t))
2782 ;; The package menu buffer has keybindings. If the user types
2783 ;; `M-x list-packages', that suggests it should become current.
2784 (switch-to-buffer buf))
2785
2786 (let ((upgrades (package-menu--find-upgrades)))
2787 (if upgrades
2788 (message "%d package%s can be upgraded; type `%s' to mark %s for upgrading."
2789 (length upgrades)
2790 (if (= (length upgrades) 1) "" "s")
2791 (substitute-command-keys "\\[package-menu-mark-upgrades]")
2792 (if (= (length upgrades) 1) "it" "them"))))))
2793 2824
2794;;;###autoload 2825;;;###autoload
2795(defalias 'package-list-packages 'list-packages) 2826(defalias 'package-list-packages 'list-packages)