From a3fd87cb69eb4e93238a2701118559bee9d493eb Mon Sep 17 00:00:00 2001 From: Tassilo Horn Date: Tue, 30 Jul 2013 08:16:20 +0000 Subject: [PATCH] Gnus: Improve subthread sorting; make subthread sorting customizable and add docs for it * doc/misc/gnus.texi (Sorting the Summary Buffer): Document new defcustom `gnus-subthread-sort-functions' and remove the obsolete documentation of `gnus-sort-threads-recursively'. * lisp/gnus/gnus-sum.el (gnus-subthread-sort-functions): New defcustom. (gnus-sort-threads-recursively): Delete defcustom. (gnus-sort-threads-recursive): Adapt accordingly. * lisp/gnus/gnus-sum.el (gnus-sort-subthreads-recursive): New function. (gnus-sort-threads-recursive): Use it. (gnus-sort-threads): Unconditionally call `gnus-sort-threads-recursive' again. Now that determines how to sort subthreads. --- doc/misc/ChangeLog | 8 +++++- doc/misc/gnus.texi | 11 ++++++--- lisp/gnus/ChangeLog | 13 ++++++++++ lisp/gnus/gnus-sum.el | 57 +++++++++++++++++++++++++++++++++---------- 4 files changed, 71 insertions(+), 18 deletions(-) diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog index b306ce5ba0a..9b45ac06f4c 100644 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog @@ -1,4 +1,10 @@ -2013-07-29 David Engster +2013-07-30 Tassilo Horn + + * gnus.texi (Sorting the Summary Buffer): Document new defcustom + `gnus-subthread-sort-functions' and remove the obsolete documentation + of `gnus-sort-threads-recursively'. + +2013-07-29 David Engster * eieio.texi (top): Make clear that EIEIO is not a full CLOS implementation. diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi index 5f9e0b9db28..808bd2b114b 100644 --- a/doc/misc/gnus.texi +++ b/doc/misc/gnus.texi @@ -7394,10 +7394,13 @@ say something like: gnus-thread-sort-by-score)) @end lisp -By default, threads are sorted recursively, that is, first the roots, -then all subthreads, and so on. If you feel more like sorting only -the roots, so that inside a thread the original chronological order is -retained, you can set @code{gnus-sort-threads-recursively} to nil. +By default, threads including their subthreads are sorted according to +the value of @code{gnus-thread-sort-functions}. By customizing +@code{gnus-subthread-sort-functions} you can define a custom sorting +order for subthreads. This allows for example to sort threads from +high score to low score in the summary buffer, but to have subthreads +still sorted chronologically from old to new without taking their +score into account. @vindex gnus-thread-score-function The function in the @code{gnus-thread-score-function} variable (default diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index c32853a2a9f..4230d010a5d 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog @@ -1,3 +1,16 @@ +2013-07-30 Tassilo Horn + + * gnus-sum.el (gnus-subthread-sort-functions): New defcustom. + (gnus-sort-threads-recursively): Delete defcustom. + (gnus-sort-threads-recursive): Adapt accordingly. + +2013-07-30 Tassilo Horn + + * gnus-sum.el (gnus-sort-subthreads-recursive): New function. + (gnus-sort-threads-recursive): Use it. + (gnus-sort-threads): Unconditionally call `gnus-sort-threads-recursive' + again. Now that determines how to sort subthreads. + 2013-07-26 Tassilo Horn * gnus-sum.el (gnus-sort-threads-recursively): New defcustom. diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index 15cbb5a45e6..a7269baee74 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -847,14 +847,6 @@ controls how articles are sorted." (function :tag "other")) (boolean :tag "Reverse order")))) -(defcustom gnus-sort-threads-recursively t - "If non-nil, `gnus-thread-sort-functions' are applied recursively. -Setting this to nil allows sorting high-score, recent, -etc. threads to the top of the summary buffer while still -retaining chronological old to new sorting order inside threads." - :group 'gnus-summary-sort - :type 'boolean) - (defcustom gnus-thread-sort-functions '(gnus-thread-sort-by-number) "*List of functions used for sorting threads in the summary buffer. By default, threads are sorted by article number. @@ -880,7 +872,11 @@ and `gnus-thread-sort-by-total-score' (see `gnus-thread-score-function'). When threading is turned off, the variable -`gnus-article-sort-functions' controls how articles are sorted." +`gnus-article-sort-functions' controls how articles are sorted. + +By default, threads and their subthreads are sorted according to +the value of this variable. To use a different sorting order for +subthreads, customize `gnus-subthread-sort-functions'." :group 'gnus-summary-sort :type '(repeat (gnus-widget-reversible @@ -897,6 +893,28 @@ When threading is turned off, the variable (function :tag "other")) (boolean :tag "Reverse order")))) +(defcustom gnus-subthread-sort-functions 'gnus-thread-sort-functions + "*List of functions used for sorting subthreads in the summary buffer. +By default, subthreads are sorted the same as threads, i.e., +according to the value of `gnus-thread-sort-functions'." + :group 'gnus-summary-sort + :type '(choice + (const :tag "Sort subthreads like threads" gnus-thread-sort-functions) + (repeat + (gnus-widget-reversible + (choice (function-item gnus-thread-sort-by-number) + (function-item gnus-thread-sort-by-author) + (function-item gnus-thread-sort-by-recipient) + (function-item gnus-thread-sort-by-subject) + (function-item gnus-thread-sort-by-date) + (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-random) + (function-item gnus-thread-sort-by-total-score) + (function :tag "other")) + (boolean :tag "Reverse order"))))) + (defcustom gnus-thread-score-function '+ "*Function used for calculating the total score of a thread. @@ -4854,10 +4872,25 @@ If LINE, insert the rebuilt thread starting on line LINE." (gnus-delete-line))))))) (defun gnus-sort-threads-recursive (threads func) + ;; Responsible for sorting the root articles of threads. + (let ((subthread-sort-func (if (eq gnus-subthread-sort-functions + 'gnus-thread-sort-functions) + func + (gnus-make-sort-function + gnus-subthread-sort-functions)))) + (sort (mapcar (lambda (thread) + (cons (car thread) + (and (cdr thread) + (gnus-sort-subthreads-recursive + (cdr thread) subthread-sort-func)))) + threads) func))) + +(defun gnus-sort-subthreads-recursive (threads func) + ;; Responsible for sorting subthreads. (sort (mapcar (lambda (thread) (cons (car thread) (and (cdr thread) - (gnus-sort-threads-recursive (cdr thread) func)))) + (gnus-sort-subthreads-recursive (cdr thread) func)))) threads) func)) (defun gnus-sort-threads-loop (threads func) @@ -4885,9 +4918,7 @@ If LINE, insert the rebuilt thread starting on line LINE." (condition-case nil (let ((max-lisp-eval-depth (max max-lisp-eval-depth 5000)) (sort-func (gnus-make-sort-function gnus-thread-sort-functions))) - (if gnus-sort-threads-recursively - (gnus-sort-threads-recursive threads sort-func) - (sort threads sort-func))) + (gnus-sort-threads-recursive threads sort-func)) ;; Even after binding max-lisp-eval-depth, the recursive ;; sorter might fail for very long threads. In that case, ;; try using a (less well-tested) non-recursive sorter. -- 2.39.2