unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#49081: 28.0.50; [PATCH] Feature suggestion, Gnus summary mode sorting for extra headers
@ 2021-06-17 23:53 Alex Bochannek
  2021-06-19 13:14 ` Lars Ingebrigtsen
  0 siblings, 1 reply; 5+ messages in thread
From: Alex Bochannek @ 2021-06-17 23:53 UTC (permalink / raw)
  To: 49081

[-- Attachment #1: Type: text/plain, Size: 699 bytes --]

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

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 9064 bytes --]

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))

[-- Attachment #3: Type: text/plain, Size: 10 bytes --]

-- 
Alex.

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* bug#49081: 28.0.50; [PATCH] Feature suggestion, Gnus summary mode sorting for extra headers
  2021-06-17 23:53 bug#49081: 28.0.50; [PATCH] Feature suggestion, Gnus summary mode sorting for extra headers Alex Bochannek
@ 2021-06-19 13:14 ` Lars Ingebrigtsen
  2021-06-19 19:08   ` Alex Bochannek
  0 siblings, 1 reply; 5+ messages in thread
From: Lars Ingebrigtsen @ 2021-06-19 13:14 UTC (permalink / raw)
  To: Alex Bochannek; +Cc: 49081

Alex Bochannek <alex@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





^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#49081: 28.0.50; [PATCH] Feature suggestion, Gnus summary mode sorting for extra headers
  2021-06-19 13:14 ` Lars Ingebrigtsen
@ 2021-06-19 19:08   ` Alex Bochannek
  2021-06-21 12:36     ` Lars Ingebrigtsen
  0 siblings, 1 reply; 5+ messages in thread
From: Alex Bochannek @ 2021-06-19 19:08 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 49081

[-- Attachment #1: Type: text/plain, Size: 1466 bytes --]

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Alex Bochannek <alex@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.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 2172 bytes --]

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

[-- Attachment #3: Type: text/plain, Size: 368 bytes --]

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.

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* bug#49081: 28.0.50; [PATCH] Feature suggestion, Gnus summary mode sorting for extra headers
  2021-06-19 19:08   ` Alex Bochannek
@ 2021-06-21 12:36     ` Lars Ingebrigtsen
  2021-06-21 18:22       ` Alex Bochannek
  0 siblings, 1 reply; 5+ messages in thread
From: Lars Ingebrigtsen @ 2021-06-21 12:36 UTC (permalink / raw)
  To: Alex Bochannek; +Cc: 49081

Alex Bochannek <alex@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





^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#49081: 28.0.50; [PATCH] Feature suggestion, Gnus summary mode sorting for extra headers
  2021-06-21 12:36     ` Lars Ingebrigtsen
@ 2021-06-21 18:22       ` Alex Bochannek
  0 siblings, 0 replies; 5+ messages in thread
From: Alex Bochannek @ 2021-06-21 18:22 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 49081

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Alex Bochannek <alex@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.





^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-06-21 18:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-17 23:53 bug#49081: 28.0.50; [PATCH] Feature suggestion, Gnus summary mode sorting for extra headers Alex Bochannek
2021-06-19 13:14 ` Lars Ingebrigtsen
2021-06-19 19:08   ` Alex Bochannek
2021-06-21 12:36     ` Lars Ingebrigtsen
2021-06-21 18:22       ` Alex Bochannek

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).