(defvar package--downloads-in-progress nil
"List of in-progress asynchronous downloads.")
+(defvar package--all-keywords nil
+ "List of known keywords.
+Generated by `package-all-keywords'. Reset to nil whenever the
+package archives are retrieved.")
+
(declare-function epg-check-configuration "epg-config"
(config &optional minimum-version))
(declare-function epg-configuration "epg-config" ())
Optional argument ASYNC specifies whether to perform the
downloads in the background."
(interactive)
- ;; FIXME: Do it asynchronously.
(unless (file-exists-p package-user-dir)
(make-directory package-user-dir t))
+ (setq package--all-keywords nil)
(let ((default-keyring (expand-file-name "package-keyring.gpg"
data-directory))
(package--silence async))
(defun package-all-keywords ()
"Collect all package keywords"
- (let (keywords)
+ (unless package--all-keywords
(package--mapc (lambda (desc)
(let* ((desc-keywords (and desc (package-desc--keywords desc))))
- (setq keywords (append keywords desc-keywords)))))
- keywords))
+ (setq package--all-keywords (append desc-keywords package--all-keywords))))))
+ package--all-keywords)
(defun package--mapc (function &optional packages)
"Call FUNCTION for all known PACKAGES.
(defun package-menu-filter (keyword)
"Filter the *Packages* buffer.
Show only those items that relate to the specified KEYWORD.
+KEYWORD can be a string or a list of strings. If it is a list, a
+package will be displayed if it matches any of the keywords.
+Interactively, it is a list of strings separated by commas.
+
To restore the full package list, type `q'."
- (interactive (list (completing-read "Keyword: " (package-all-keywords))))
- (package-show-package-list t (list keyword)))
+ (interactive
+ (list (completing-read-multiple
+ "Keywords (comma separated): " (package-all-keywords))))
+ (package-show-package-list t (if (stringp keyword)
+ (list keyword)
+ keyword)))
(defun package-list-packages-no-fetch ()
"Display a list of packages.