From a444bb78ad5d1a06f8d5b043e16941fdcc24de16 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Mon, 16 Sep 2019 09:29:48 +0200 Subject: [PATCH] Improve sorting in package list (Bug#37419) * lisp/emacs-lisp/package.el (package-menu-mode): Allow sorting by version or description. (package-menu--version-predicate): Fix sorting by version. (package-menu--description-predicate): Fix sorting by description. (package-menu--archive-predicate): Fall back to sorting by name if archive is the same. (package-menu--name-predicate, package-menu--status-predicate): Add doc string. * etc/NEWS: Announce the above changes. --- etc/NEWS | 3 +++ lisp/emacs-lisp/package.el | 29 +++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 97b96d1e4e..34b7a5aa29 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -983,6 +983,9 @@ early init file. --- *** Imenu support has been added to 'package-menu-mode'. +--- +*** The package list can now be sorted by version or description. + ** Info +++ diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index a8362cb205..ab1fb8b90f 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -2725,11 +2725,11 @@ package-menu-mode package-menu--transaction-status))) (setq tabulated-list-format `[("Package" 18 package-menu--name-predicate) - ("Version" 13 nil) + ("Version" 13 package-menu--version-predicate) ("Status" 10 package-menu--status-predicate) ,@(if (cdr package-archives) '(("Archive" 10 package-menu--archive-predicate))) - ("Description" 0 nil)]) + ("Description" 0 package-menu--description-predicate)]) (setq tabulated-list-padding 2) (setq tabulated-list-sort-key (cons "Status" nil)) (add-hook 'tabulated-list-revert-hook #'package-menu--refresh nil t) @@ -3469,13 +3469,17 @@ package-menu-execute (message "Operation %s finished" message-template)))))))) (defun package-menu--version-predicate (A B) - (let ((vA (or (aref (cadr A) 1) '(0))) - (vB (or (aref (cadr B) 1) '(0)))) + "Predicate to sort \"*Packages*\" buffer by the version column. +This is used for `tabulated-list-format' in `package-menu-mode'." + (let ((vA (or (version-to-list (aref (cadr A) 1)) '(0))) + (vB (or (version-to-list (aref (cadr B) 1)) '(0)))) (if (version-list-= vA vB) (package-menu--name-predicate A B) (version-list-< vA vB)))) (defun package-menu--status-predicate (A B) + "Predicate to sort \"*Packages*\" buffer by the status column. +This is used for `tabulated-list-format' in `package-menu-mode'." (let ((sA (aref (cadr A) 2)) (sB (aref (cadr B) 2))) (cond ((string= sA sB) @@ -3506,19 +3510,28 @@ package-menu--status-predicate (t (string< sA sB))))) (defun package-menu--description-predicate (A B) - (let ((dA (aref (cadr A) 3)) - (dB (aref (cadr B) 3))) + "Predicate to sort \"*Packages*\" buffer by the description column. +This is used for `tabulated-list-format' in `package-menu-mode'." + (let ((dA (aref (cadr A) (if (cdr package-archives) 4 3))) + (dB (aref (cadr B) (if (cdr package-archives) 4 3)))) (if (string= dA dB) (package-menu--name-predicate A B) (string< dA dB)))) (defun package-menu--name-predicate (A B) + "Predicate to sort \"*Packages*\" buffer by the name column. +This is used for `tabulated-list-format' in `package-menu-mode'." (string< (symbol-name (package-desc-name (car A))) (symbol-name (package-desc-name (car B))))) (defun package-menu--archive-predicate (A B) - (string< (or (package-desc-archive (car A)) "") - (or (package-desc-archive (car B)) ""))) + "Predicate to sort \"*Packages*\" buffer by the archive column. +This is used for `tabulated-list-format' in `package-menu-mode'." + (let ((a (or (package-desc-archive (car A)) "")) + (b (or (package-desc-archive (car B)) ""))) + (if (string= a b) + (package-menu--name-predicate A B) + (string< a b)))) (defun package-menu--populate-new-package-list () "Decide which packages are new in `package-archives-contents'. -- 2.20.1