From 1293ece4613319629f08926d78b6cd5afdc9b2e9 Mon Sep 17 00:00:00 2001 From: Alex Bochannek Date: Sat, 19 Jun 2021 15:13:12 +0200 Subject: [PATCH] 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 (bug#49081). --- doc/misc/gnus.texi | 18 ++++++++++++-- etc/NEWS | 6 +++++ lisp/gnus/gnus-sum.el | 57 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi index ff8404e5320..c9b5b2d9ffd 100644 --- a/doc/misc/gnus.texi +++ b/doc/misc/gnus.texi @@ -7527,6 +7527,7 @@ Matching}). @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 @@ -7544,6 +7545,7 @@ predicate functions include @code{gnus-thread-sort-by-number}, @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}. @@ -7605,6 +7607,7 @@ tickles your fancy. @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 @@ -7616,8 +7619,8 @@ different functions for article comparison. Available sorting 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: @@ -10405,6 +10408,17 @@ Sort by article ``readedness'' marks (@code{gnus-summary-sort-by-marks}). @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 da1372baf4c..b5c1fa79ff8 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 bcd76dda29f..908c10c11d7 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -879,8 +879,9 @@ this reverses the sort order. 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 @@ controls how articles are sorted." (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 @@ Ready-made functions include `gnus-thread-sort-by-number', `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 @@ subthreads, customize `gnus-subthread-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 @@ according to the value of `gnus-thread-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 @@ increase the score of each group you read." "\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-show-article-from-menu-as-charset-%s" cs)))) ["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,23 @@ Unscored articles will be counted as having a score of zero." "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." + (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)))) + +(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 +12147,12 @@ Argument REVERSE means reverse order." (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 +12164,24 @@ Argument REVERSE means reverse order." ;; 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)) -- 2.39.5