summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/package.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp/package.el')
-rw-r--r--lisp/emacs-lisp/package.el80
1 files changed, 68 insertions, 12 deletions
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 1f81e07754b..b7c48dfd3f5 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -982,7 +982,8 @@ untar into a directory named DIR; otherwise, signal an error."
(write-region
(concat
";;; Generated package description from "
- (replace-regexp-in-string "-pkg\\.el\\'" ".el" pkg-file)
+ (replace-regexp-in-string "-pkg\\.el\\'" ".el"
+ (file-name-nondirectory pkg-file))
" -*- no-byte-compile: t -*-\n"
(prin1-to-string
(nconc
@@ -1114,14 +1115,15 @@ boundaries."
;; Use some headers we've invented to drive the process.
(let* (;; Prefer Package-Version; if defined, the package author
;; probably wants us to use it. Otherwise try Version.
- (pkg-version
- (or (package-strip-rcs-id (lm-header "package-version"))
- (package-strip-rcs-id (lm-header "version"))))
+ (version-info
+ (or (lm-header "package-version") (lm-header "version")))
+ (pkg-version (package-strip-rcs-id version-info))
(keywords (lm-keywords-list))
(homepage (lm-homepage)))
(unless pkg-version
- (error
- "Package lacks a \"Version\" or \"Package-Version\" header"))
+ (if version-info
+ (error "Unrecognized package version: %s" version-info)
+ (error "Package lacks a \"Version\" or \"Package-Version\" header")))
(package-desc-from-define
file-name pkg-version desc
(and-let* ((require-lines (lm-header-multiline "package-requires")))
@@ -2111,8 +2113,10 @@ Otherwise return nil."
(when str
(when (string-match "\\`[ \t]*[$]Revision:[ \t]+" str)
(setq str (substring str (match-end 0))))
- (ignore-errors
- (if (version-to-list str) str))))
+ (let ((l (version-to-list str)))
+ ;; Don't return `str' but (package-version-join (version-to-list str))
+ ;; to make sure we use a "canonical name"!
+ (if l (package-version-join l)))))
(declare-function lm-homepage "lisp-mnt" (&optional file))
@@ -2152,6 +2156,7 @@ Downloads and installs required packages as needed."
(unless (package--user-selected-p name)
(package--save-selected-packages
(cons name package-selected-packages)))
+ (package--quickstart-maybe-refresh)
pkg-desc))
;;;###autoload
@@ -2630,8 +2635,7 @@ Used for the `action' property of buttons in the buffer created by
(when (y-or-n-p (format-message "Install package `%s'? "
(package-desc-full-name pkg-desc)))
(package-install pkg-desc nil)
- (revert-buffer nil t)
- (goto-char (point-min)))))
+ (describe-package (package-desc-name pkg-desc)))))
(defun package-delete-button-action (button)
"Run `package-delete' on the package BUTTON points to.
@@ -2641,8 +2645,7 @@ Used for the `action' property of buttons in the buffer created by
(when (y-or-n-p (format-message "Delete package `%s'? "
(package-desc-full-name pkg-desc)))
(package-delete pkg-desc)
- (revert-buffer nil t)
- (goto-char (point-min)))))
+ (describe-package (package-desc-name pkg-desc)))))
(defun package-keyword-button-action (button)
"Show filtered \"*Packages*\" buffer for BUTTON.
@@ -2704,11 +2707,14 @@ either a full name or nil, and EMAIL is a valid email address."
(define-key map "(" #'package-menu-toggle-hiding)
(define-key map (kbd "/ /") 'package-menu-clear-filter)
(define-key map (kbd "/ a") 'package-menu-filter-by-archive)
+ (define-key map (kbd "/ d") 'package-menu-filter-by-description)
(define-key map (kbd "/ k") 'package-menu-filter-by-keyword)
+ (define-key map (kbd "/ N") 'package-menu-filter-by-name-or-description)
(define-key map (kbd "/ n") 'package-menu-filter-by-name)
(define-key map (kbd "/ s") 'package-menu-filter-by-status)
(define-key map (kbd "/ v") 'package-menu-filter-by-version)
(define-key map (kbd "/ m") 'package-menu-filter-marked)
+ (define-key map (kbd "/ u") 'package-menu-filter-upgradable)
map)
"Local keymap for `package-menu-mode' buffers.")
@@ -2735,8 +2741,11 @@ either a full name or nil, and EMAIL is a valid email address."
"--"
("Filter Packages"
["Filter by Archive" package-menu-filter-by-archive :help "Filter packages by archive"]
+ ["Filter by Description" package-menu-filter-by-description :help "Filter packages by description"]
["Filter by Keyword" package-menu-filter-by-keyword :help "Filter packages by keyword"]
["Filter by Name" package-menu-filter-by-name :help "Filter packages by name"]
+ ["Filter by Name or Description" package-menu-filter-by-name-or-description
+ :help "Filter packages by name or description"]
["Filter by Status" package-menu-filter-by-status :help "Filter packages by status"]
["Filter by Version" package-menu-filter-by-version :help "Filter packages by version"]
["Filter Marked" package-menu-filter-marked :help "Filter packages marked for upgrade"]
@@ -3764,6 +3773,23 @@ packages."
(string-join archive ",")
archive)))))
+(defun package-menu-filter-by-description (description)
+ "Filter the \"*Packages*\" buffer by DESCRIPTION regexp.
+Display only packages with a description that matches regexp
+DESCRIPTION.
+
+When called interactively, prompt for DESCRIPTION.
+
+If DESCRIPTION is nil or the empty string, show all packages."
+ (interactive (list (read-regexp "Filter by description (regexp)")))
+ (package--ensure-package-menu-mode)
+ (if (or (not description) (string-empty-p description))
+ (package-menu--generate t t)
+ (package-menu--filter-by (lambda (pkg-desc)
+ (string-match description
+ (package-desc-summary pkg-desc)))
+ (format "desc:%s" description))))
+
(defun package-menu-filter-by-keyword (keyword)
"Filter the \"*Packages*\" buffer by KEYWORD.
Display only packages with specified KEYWORD.
@@ -3789,6 +3815,27 @@ packages."
(define-obsolete-function-alias
'package-menu-filter #'package-menu-filter-by-keyword "27.1")
+(defun package-menu-filter-by-name-or-description (name-or-description)
+ "Filter the \"*Packages*\" buffer by NAME-OR-DESCRIPTION regexp.
+Display only packages with a name-or-description that matches regexp
+NAME-OR-DESCRIPTION.
+
+When called interactively, prompt for NAME-OR-DESCRIPTION.
+
+If NAME-OR-DESCRIPTION is nil or the empty string, show all
+packages."
+ (interactive (list (read-regexp "Filter by name or description (regexp)")))
+ (package--ensure-package-menu-mode)
+ (if (or (not name-or-description) (string-empty-p name-or-description))
+ (package-menu--generate t t)
+ (package-menu--filter-by (lambda (pkg-desc)
+ (or (string-match name-or-description
+ (package-desc-summary pkg-desc))
+ (string-match name-or-description
+ (symbol-name
+ (package-desc-name pkg-desc)))))
+ (format "name-or-desc:%s" name-or-description))))
+
(defun package-menu-filter-by-name (name)
"Filter the \"*Packages*\" buffer by NAME regexp.
Display only packages with name that matches regexp NAME.
@@ -3905,6 +3952,15 @@ Unlike other filters, this leaves the marks intact."
(tabulated-list-put-tag (char-to-string mark) t)))
(user-error "No packages found")))))
+(defun package-menu-filter-upgradable ()
+ "Filter \"*Packages*\" buffer to show only upgradable packages."
+ (interactive)
+ (let ((pkgs (mapcar #'car (package-menu--find-upgrades))))
+ (package-menu--filter-by
+ (lambda (pkg)
+ (memql (package-desc-name pkg) pkgs))
+ "upgradable")))
+
(defun package-menu-clear-filter ()
"Clear any filter currently applied to the \"*Packages*\" buffer."
(interactive)