GNU bug report logs - #49081
28.0.50; [PATCH] Feature suggestion, Gnus summary mode sorting for extra headers

Previous Next

Package: emacs;

Reported by: Alex Bochannek <alex <at> bochannek.com>

Date: Thu, 17 Jun 2021 23:54:02 UTC

Severity: normal

Tags: patch

Found in version 28.0.50

Fixed in version 28.1

Done: Lars Ingebrigtsen <larsi <at> gnus.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 49081 in the body.
You can then email your comments to 49081 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#49081; Package emacs. (Thu, 17 Jun 2021 23:54:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Alex Bochannek <alex <at> bochannek.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Thu, 17 Jun 2021 23:54:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Alex Bochannek <alex <at> bochannek.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 28.0.50; [PATCH] Feature suggestion, Gnus summary mode sorting for
 extra headers
Date: Thu, 17 Jun 2021 16:53:11 -0700
[Message part 1 (text/plain, inline)]
Hello!

Since I was able to get the Newsgroups extra header working for
`nnvirtual' groups, I would like to not only limit, but also sort by the
extra headers.

Thanks!

	New Gnus Summary buffer sort options for extra headers

	* lisp/gnus/gnus-sum.el (gnus-article-sort-functions)
	(gnus-thread-sort-functions, gnus-subthread-sort-functions)
	(gnus-summary-mode-map, gnus-summary-make-menu-bar)
	(gnus-article-sort-by-newsgroups)
	(gnus-summary-sort-by-newsgroups, gnus-summary-sort-by-extra):
	Sort by Newsgroups extra header. Prompt for header name for other
	extra headers.

	* doc/misc/gnus.texi (Summary Sorting): Document new sort functions

	* etc/NEWS: New Gnus Summary buffer sort feature
[Message part 2 (text/x-patch, inline)]
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index b63947c044..c9b5b2d9ff 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -4126,6 +4126,8 @@ Topic Variables
 Level.
 @item g
 Number of groups in the topic.
+@item G
+Number of groups in the topic and all its subtopics.
 @item a
 Number of unread articles in the topic.
 @item A
@@ -7525,6 +7527,7 @@ Sorting the Summary Buffer
 @findex gnus-thread-sort-by-author
 @findex gnus-thread-sort-by-recipient
 @findex gnus-thread-sort-by-number
+@findex gnus-thread-sort-by-newsgroups
 @findex gnus-thread-sort-by-random
 @vindex gnus-thread-sort-functions
 @findex gnus-thread-sort-by-most-recent-number
@@ -7542,6 +7545,7 @@ Sorting the Summary Buffer
 @code{gnus-thread-sort-by-score},
 @code{gnus-thread-sort-by-most-recent-number},
 @code{gnus-thread-sort-by-most-recent-date},
+@code{gnus-thread-sort-by-newsgroups} and
 @code{gnus-thread-sort-by-random} and
 @code{gnus-thread-sort-by-total-score}.
 
@@ -7603,6 +7607,7 @@ Sorting the Summary Buffer
 @findex gnus-article-sort-by-score
 @findex gnus-article-sort-by-subject
 @findex gnus-article-sort-by-author
+@findex gnus-article-sort-by-newsgroups
 @findex gnus-article-sort-by-random
 @findex gnus-article-sort-by-number
 @findex gnus-article-sort-by-most-recent-number
@@ -7614,8 +7619,8 @@ Sorting the Summary Buffer
 predicate functions are @code{gnus-article-sort-by-number},
 @code{gnus-article-sort-by-author},
 @code{gnus-article-sort-by-subject}, @code{gnus-article-sort-by-date},
-@code{gnus-article-sort-by-random}, and
-@code{gnus-article-sort-by-score}.
+@code{gnus-article-sort-by-newsgroups}, @code{gnus-article-sort-by-random},
+and @code{gnus-article-sort-by-score}.
 
 If you want to sort an unthreaded summary display by subject, you could
 say something like:
@@ -10403,6 +10408,17 @@ Summary Sorting
 @findex gnus-summary-sort-by-score
 Sort by score (@code{gnus-summary-sort-by-score}).
 
+@item C-c C-s C-u
+@kindex C-c C-s C-u @r{(Summary)}
+@findex gnus-summary-sort-by-newsgroups
+Sort by newsgroups (@code{gnus-summary-sort-by-newsgroups}).
+
+@item C-c C-s C-x
+@kindex C-c C-s C-x @r{(Summary)}
+@findex gnus-summary-sort-by-extra
+Prompts for extra header to sort by (@code{gnus-summary-sort-by-extra}).
+An error will be raised if no sort functions for the header are defined.
+
 @item C-c C-s C-r
 @kindex C-c C-s C-r @r{(Summary)}
 @findex gnus-summary-sort-by-random
diff --git a/etc/NEWS b/etc/NEWS
index da1372baf4..b5c1fa79ff 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -897,6 +897,12 @@ String or list of strings specifying switches for Git log under VC.
 
 ** Gnus
 
++++
+*** New Summary buffer sort options for extra headers.
+The extra header sort option ('C-c C-s C-x') prompts for a header
+and fails if no sort function has been defined. Sorting by
+Newsgroups ('C-c C-s C-u') has been pre-defined.
+
 +++
 *** The '#' command in the Group and Summary buffer now toggles,
 instead of sets, the process mark.
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index bcd76dda29..7c5d3833f1 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -879,8 +879,9 @@ gnus-article-sort-functions
 
 Ready-made functions include `gnus-article-sort-by-number',
 `gnus-article-sort-by-author', `gnus-article-sort-by-subject',
-`gnus-article-sort-by-date', `gnus-article-sort-by-random'
-and `gnus-article-sort-by-score'.
+`gnus-article-sort-by-date', `gnus-article-sort-by-score',
+`gnus-article-sort-by-rsv', `gnus-article-sort-by-newsgroups',
+and `gnus-article-sort-by-random'.
 
 When threading is turned on, the variable `gnus-thread-sort-functions'
 controls how articles are sorted."
@@ -892,6 +893,7 @@ gnus-article-sort-functions
                           (function-item gnus-article-sort-by-date)
                           (function-item gnus-article-sort-by-score)
                           (function-item gnus-article-sort-by-rsv)
+                          (function-item gnus-article-sort-by-newsgroups)
                           (function-item gnus-article-sort-by-random)
                           (function :tag "other"))
                   (boolean :tag "Reverse order"))))
@@ -916,8 +918,8 @@ gnus-thread-sort-functions
 `gnus-thread-sort-by-author', `gnus-thread-sort-by-recipient'
 `gnus-thread-sort-by-subject', `gnus-thread-sort-by-date',
 `gnus-thread-sort-by-score', `gnus-thread-sort-by-most-recent-number',
-`gnus-thread-sort-by-most-recent-date', `gnus-thread-sort-by-random',
-and `gnus-thread-sort-by-total-score' (see
+`gnus-thread-sort-by-most-recent-date', `gnus-thread-sort-by-newsgroups',
+`gnus-thread-sort-by-random', and `gnus-thread-sort-by-total-score' (see
 `gnus-thread-score-function').
 
 When threading is turned off, the variable
@@ -938,6 +940,7 @@ gnus-thread-sort-functions
                    (function-item gnus-thread-sort-by-rsv)
                    (function-item gnus-thread-sort-by-most-recent-number)
                    (function-item gnus-thread-sort-by-most-recent-date)
+                   (function-item gnus-thread-sort-by-newsgroups)
                    (function-item gnus-thread-sort-by-random)
                    (function-item gnus-thread-sort-by-total-score)
                    (function :tag "other"))
@@ -961,6 +964,7 @@ gnus-subthread-sort-functions
 		    (function-item gnus-thread-sort-by-score)
 		    (function-item gnus-thread-sort-by-most-recent-number)
 		    (function-item gnus-thread-sort-by-most-recent-date)
+                    (function-item gnus-thread-sort-by-newsgroups)
 		    (function-item gnus-thread-sort-by-random)
 		    (function-item gnus-thread-sort-by-total-score)
 		    (function :tag "other"))
@@ -1976,6 +1980,8 @@ gnus-summary-mode-map
   "\C-c\C-s\C-i" gnus-summary-sort-by-score
   "\C-c\C-s\C-o" gnus-summary-sort-by-original
   "\C-c\C-s\C-r" gnus-summary-sort-by-random
+  "\C-c\C-s\C-u" gnus-summary-sort-by-newsgroups
+  "\C-c\C-s\C-x" gnus-summary-sort-by-extra
   "=" gnus-summary-expand-window
   "\C-x\C-s" gnus-summary-reselect-current-group
   "\M-g" gnus-summary-rescan-group
@@ -2831,6 +2837,8 @@ gnus-summary-make-menu-bar
 	 ["Sort by lines" gnus-summary-sort-by-lines t]
 	 ["Sort by characters" gnus-summary-sort-by-chars t]
 	 ["Sort by marks" gnus-summary-sort-by-marks t]
+	 ["Sort by newsgroup" gnus-summary-sort-by-newsgroups t]
+	 ["Sort by extra" gnus-summary-sort-by-extra t]
 	 ["Randomize" gnus-summary-sort-by-random t]
 	 ["Original sort" gnus-summary-sort-by-original t])
 	("Help"
@@ -5180,6 +5188,24 @@ gnus-thread-sort-by-most-recent-date
   "Sort threads such that the thread with the most recently dated article comes first."
   (> (gnus-thread-latest-date h1) (gnus-thread-latest-date h2)))
 
+(defun gnus-article-sort-by-newsgroups (h1 h2)
+  "Sort articles by newsgroups."
+  (gnus-string<
+   (let ((extract (funcall
+		   gnus-extract-address-components
+		   (or (cdr (assq 'Newsgroups (mail-header-extra h1))) ""))))
+     (or (car extract) (cadr extract)))
+   (let ((extract (funcall
+		   gnus-extract-address-components
+		   (or (cdr (assq 'Newsgroups (mail-header-extra h2))) ""))))
+     (or (car extract) (cadr extract)))))
+
+(defun gnus-thread-sort-by-newsgroups (h1 h2)
+  "Sort threads by root newsgroups."
+  (gnus-article-sort-by-newsgroups
+   (gnus-thread-header h1) (gnus-thread-header h2)))
+
+
 ; Since this is called not only to sort the top-level threads, but
 ; also in recursive sorts to order the articles within a thread, each
 ; article will be processed many times.  Thus it speeds things up
@@ -12122,6 +12148,12 @@ gnus-summary-sort-by-marks
   (interactive "P" gnus-summary-mode)
   (gnus-summary-sort 'marks reverse))
 
+(defun gnus-summary-sort-by-newsgroups (&optional reverse)
+  "Sort the summary buffer by newsgroups alphabetically.
+Argument REVERSE means reverse order."
+  (interactive "P" gnus-summary-mode)
+  (gnus-summary-sort 'newsgroups reverse))
+
 (defun gnus-summary-sort-by-original (&optional _reverse)
   "Sort the summary buffer using the default sorting method.
 Argument REVERSE means reverse order."
@@ -12133,6 +12165,24 @@ gnus-summary-sort-by-original
     ;; Hide subthreads if needed.
     (gnus-summary-maybe-hide-threads)))
 
+(defun gnus-summary-sort-by-extra (&optional reverse)
+  "Sort the summary buffer using an extra header.
+Argument REVERSE means reverse order."
+  (interactive "P" gnus-summary-mode)
+  (let* ((extra-header
+	  (gnus-completing-read "Sort by extra header"
+	   (mapcar #'symbol-name gnus-extra-headers)
+	   t nil nil
+	   (symbol-name
+	    (car gnus-extra-headers))))
+	(header (downcase extra-header)))
+    (if (and (fboundp (intern
+		       (format "gnus-thread-sort-by-%s" header)))
+	     (fboundp
+	      (intern (format "gnus-article-sort-by-%s" header))))
+	(gnus-summary-sort header reverse)
+      (error "No sort function defined for header: %s" extra-header))))
+
 (defun gnus-summary-sort (predicate reverse)
   "Sort summary buffer by PREDICATE.  REVERSE means reverse order."
   (let* ((current (gnus-summary-article-number))
[Message part 3 (text/plain, inline)]
-- 
Alex.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#49081; Package emacs. (Sat, 19 Jun 2021 13:15:01 GMT) Full text and rfc822 format available.

Message #8 received at 49081 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Alex Bochannek <alex <at> bochannek.com>
Cc: 49081 <at> debbugs.gnu.org
Subject: Re: bug#49081: 28.0.50; [PATCH] Feature suggestion, Gnus summary
 mode sorting for extra headers
Date: Sat, 19 Jun 2021 15:14:15 +0200
Alex Bochannek <alex <at> bochannek.com> writes:

> Since I was able to get the Newsgroups extra header working for
> `nnvirtual' groups, I would like to not only limit, but also sort by the
> extra headers.

Looks good; applied with one minor tweak:

> +(defun gnus-article-sort-by-newsgroups (h1 h2)
> +  "Sort articles by newsgroups."
> +  (gnus-string<
> +   (let ((extract (funcall
> +		   gnus-extract-address-components
> +		   (or (cdr (assq 'Newsgroups (mail-header-extra h1))) ""))))
> +     (or (car extract) (cadr extract)))
> +   (let ((extract (funcall
> +		   gnus-extract-address-components
> +		   (or (cdr (assq 'Newsgroups (mail-header-extra h2))) ""))))
> +     (or (car extract) (cadr extract)))))

I rewrote that to:

(defun gnus-article-sort-by-newsgroups (h1 h2)
  "Sort articles by newsgroups."
  (let ((ex
         (lambda (h)
           (let ((extract
                  (funcall gnus-extract-address-components
		           (or (cdr (assq 'Newsgroups (mail-header-extra h)))
                               ""))))
             (or (car extract) (cadr extract))))))
    (gnus-string< (funcall ex h1) (funcall ex h2))))

To avoid the duplication -- let me know if I messed up that bit.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




bug marked as fixed in version 28.1, send any further explanations to 49081 <at> debbugs.gnu.org and Alex Bochannek <alex <at> bochannek.com> Request was from Lars Ingebrigtsen <larsi <at> gnus.org> to control <at> debbugs.gnu.org. (Sat, 19 Jun 2021 13:15:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#49081; Package emacs. (Sat, 19 Jun 2021 19:09:02 GMT) Full text and rfc822 format available.

Message #13 received at 49081 <at> debbugs.gnu.org (full text, mbox):

From: Alex Bochannek <alex <at> bochannek.com>
To: Lars Ingebrigtsen <larsi <at> gnus.org>
Cc: 49081 <at> debbugs.gnu.org
Subject: Re: bug#49081: 28.0.50; [PATCH] Feature suggestion, Gnus summary
 mode sorting for extra headers
Date: Sat, 19 Jun 2021 12:08:55 -0700
[Message part 1 (text/plain, inline)]
Lars Ingebrigtsen <larsi <at> gnus.org> writes:

> Alex Bochannek <alex <at> bochannek.com> writes:
>
>> Since I was able to get the Newsgroups extra header working for
>> `nnvirtual' groups, I would like to not only limit, but also sort by the
>> extra headers.
>
> Looks good; applied with one minor tweak:
>
>> +(defun gnus-article-sort-by-newsgroups (h1 h2)
>> +  "Sort articles by newsgroups."
>> +  (gnus-string<
>> +   (let ((extract (funcall
>> +		   gnus-extract-address-components
>> +		   (or (cdr (assq 'Newsgroups (mail-header-extra h1))) ""))))
>> +     (or (car extract) (cadr extract)))
>> +   (let ((extract (funcall
>> +		   gnus-extract-address-components
>> +		   (or (cdr (assq 'Newsgroups (mail-header-extra h2))) ""))))
>> +     (or (car extract) (cadr extract)))))
>
> I rewrote that to:
>
> (defun gnus-article-sort-by-newsgroups (h1 h2)
>   "Sort articles by newsgroups."
>   (let ((ex
>          (lambda (h)
>            (let ((extract
>                   (funcall gnus-extract-address-components
> 		           (or (cdr (assq 'Newsgroups (mail-header-extra h)))
>                                ""))))
>              (or (car extract) (cadr extract))))))
>     (gnus-string< (funcall ex h1) (funcall ex h2))))
>
> To avoid the duplication -- let me know if I messed up that bit.

Looks good, thank you!

I originally had duplicated that code from
`gnus-article-sort-by-recipient' and it's probably a good idea to make
that into a utility function.
[Message part 2 (text/x-patch, inline)]
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index 908c10c11d..788676c7c8 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -5085,15 +5085,10 @@ gnus-thread-sort-by-author
 
 (defsubst gnus-article-sort-by-recipient (h1 h2)
   "Sort articles by recipient."
-  (gnus-string<
-   (let ((extract (funcall
-		   gnus-extract-address-components
-		   (or (cdr (assq 'To (mail-header-extra h1))) ""))))
-     (or (car extract) (cadr extract)))
-   (let ((extract (funcall
-		   gnus-extract-address-components
-		   (or (cdr (assq 'To (mail-header-extra h2))) ""))))
-     (or (car extract) (cadr extract)))))
+  (let ((ex
+	 (lambda (h)
+	   (gnus-article-sort-extract-extra 'To h))))
+    (gnus-string< (funcall ex h1) (funcall ex h2))))
 
 (defun gnus-thread-sort-by-recipient (h1 h2)
   "Sort threads by root recipient."
@@ -5188,15 +5183,11 @@ gnus-thread-sort-by-most-recent-date
   "Sort threads such that the thread with the most recently dated article comes first."
   (> (gnus-thread-latest-date h1) (gnus-thread-latest-date h2)))
 
-(defun gnus-article-sort-by-newsgroups (h1 h2)
+(defsubst gnus-article-sort-by-newsgroups (h1 h2)
   "Sort articles by newsgroups."
   (let ((ex
-         (lambda (h)
-           (let ((extract
-                  (funcall gnus-extract-address-components
-		           (or (cdr (assq 'Newsgroups (mail-header-extra h)))
-                               ""))))
-             (or (car extract) (cadr extract))))))
+	 (lambda (h)
+	   (gnus-article-sort-extract-extra 'Newsgroups h))))
     (gnus-string< (funcall ex h1) (funcall ex h2))))
 
 (defun gnus-thread-sort-by-newsgroups (h1 h2)
@@ -5204,6 +5195,12 @@ gnus-thread-sort-by-newsgroups
   (gnus-article-sort-by-newsgroups
    (gnus-thread-header h1) (gnus-thread-header h2)))
 
+(defsubst gnus-article-sort-extract-extra (Name header)
+    (let ((extract
+	   (funcall gnus-extract-address-components
+		    (or (cdr (assq name (mail-header-extra header)))
+			""))))
+      (or (car extract) (cadr extract))))
 
 ; Since this is called not only to sort the top-level threads, but
 ; also in recursive sorts to order the articles within a thread, each
[Message part 3 (text/plain, inline)]
A similar pattern is used by `gnus-article-sort-by-author', but I didn't
see an easy way to unify these without also passing around functions by
header type.

Also, I haven't used `defsubst' before, so I leave it up to you if it
makes sense to use that for the `gnus-article-sort-by-newsgroups' and
`gnus-article-sort-by-newsgroups', respectively.

Thanks!

-- 
Alex.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#49081; Package emacs. (Mon, 21 Jun 2021 12:37:01 GMT) Full text and rfc822 format available.

Message #16 received at 49081 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Alex Bochannek <alex <at> bochannek.com>
Cc: 49081 <at> debbugs.gnu.org
Subject: Re: bug#49081: 28.0.50; [PATCH] Feature suggestion, Gnus summary
 mode sorting for extra headers
Date: Mon, 21 Jun 2021 14:36:17 +0200
Alex Bochannek <alex <at> bochannek.com> writes:

> I originally had duplicated that code from
> `gnus-article-sort-by-recipient' and it's probably a good idea to make
> that into a utility function.

Thanks; applied (with some whitespace changes).

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#49081; Package emacs. (Mon, 21 Jun 2021 18:23:02 GMT) Full text and rfc822 format available.

Message #19 received at 49081 <at> debbugs.gnu.org (full text, mbox):

From: Alex Bochannek <alex <at> bochannek.com>
To: Lars Ingebrigtsen <larsi <at> gnus.org>
Cc: 49081 <at> debbugs.gnu.org
Subject: Re: bug#49081: 28.0.50; [PATCH] Feature suggestion, Gnus summary
 mode sorting for extra headers
Date: Mon, 21 Jun 2021 11:22:47 -0700
Lars Ingebrigtsen <larsi <at> gnus.org> writes:

> Alex Bochannek <alex <at> bochannek.com> writes:
>
>> I originally had duplicated that code from
>> `gnus-article-sort-by-recipient' and it's probably a good idea to make
>> that into a utility function.
>
> Thanks; applied (with some whitespace changes).

Looks good, thanks!

-- 
Alex.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Tue, 20 Jul 2021 11:24:10 GMT) Full text and rfc822 format available.

This bug report was last modified 2 years and 293 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.