From: Eric Abrahamsen Date: Sun, 19 May 2019 16:57:50 +0000 (-0700) Subject: Fix Gnus group sorting to use gnus-group-list X-Git-Tag: emacs-27.0.90~2818 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e4eb8c850145248c1f3c4235cdd8d11b1c05bb1e;p=emacs.git Fix Gnus group sorting to use gnus-group-list * lisp/gnus/gnus-group.el (gnus-group-sort-flat): As gnus-newsrc-hashtb is now a real (unsorted) hash table, use gnus-group-list to maintain group sort order. (gnus-group-sort-selected-flat): Ditto. * lisp/gnus/gnus-start.el (gnus-subscribe-alphabetically): Simplify function using seq-find. (gnus-subscribe-killed, gnus-subscribe-zombies): Use cl-pushnew to avoid adding duplicates (can happen when un/subscribing multiple times to one group). --- diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index c757c82fbc8..4a14de33b0d 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el @@ -3300,21 +3300,31 @@ If REVERSE (the prefix), reverse the sorting order." (funcall gnus-group-sort-alist-function (gnus-make-sort-function func) reverse) (gnus-group-unmark-all-groups) + ;; Redisplay all groups according to the newly-sorted order of + ;; `gnus-group-list'. (gnus-group-list-groups) (gnus-dribble-touch)) (defun gnus-group-sort-flat (func reverse) - ;; We peel off the dummy group from the alist. + "Sort groups in a flat list using sorting function FUNC. +If REVERSE is non-nil, reverse the sort order. + +This function sets a new value for `gnus-group-list'; its return +value is disregarded." (when func - (when (equal (gnus-info-group (car gnus-newsrc-alist)) "dummy.group") - (pop gnus-newsrc-alist)) - ;; Do the sorting. - (setq gnus-newsrc-alist - (sort gnus-newsrc-alist func)) - (when reverse - (setq gnus-newsrc-alist (nreverse gnus-newsrc-alist))) - ;; Regenerate the hash table. - (gnus-make-hashtable-from-newsrc-alist))) + (let* ((groups (remove "dummy.group" gnus-group-list)) + (sorted-infos + (sort (mapcar (lambda (g) + (gnus-get-info g)) + groups) + func))) + (setq gnus-group-list + (mapcar (lambda (i) + (gnus-info-group i)) + sorted-infos)) + (when reverse + (setq gnus-group-list (nreverse gnus-group-list))) + (setq gnus-group-list (cons "dummy.group" gnus-group-list))))) (defun gnus-group-sort-groups-by-alphabet (&optional reverse) "Sort the group buffer alphabetically by group name. @@ -3377,27 +3387,26 @@ If REVERSE, sort in reverse order." (gnus-dribble-touch))) (defun gnus-group-sort-selected-flat (groups func reverse) - (let (entries infos) - ;; First find all the group entries for these groups. - (while groups - (push (nthcdr 2 (gnus-group-entry (pop groups))) - entries)) - ;; Then sort the infos. - (setq infos - (sort - (mapcar - (lambda (entry) (car entry)) - (setq entries (nreverse entries))) - func)) + "Sort only the selected GROUPS, using FUNC. +If REVERSE is non-nil, reverse the sorting." + (let ((infos (sort + (mapcar (lambda (g) + (gnus-get-info g)) + groups) + func)) + sorted-groups) (when reverse (setq infos (nreverse infos))) - ;; Go through all the infos and replace the old entries - ;; with the new infos. - (while infos - (setcar (car entries) (pop infos)) - (pop entries)) - ;; Update the hashtable. - (gnus-make-hashtable-from-newsrc-alist))) + (setq sorted-groups (mapcar (lambda (i) (gnus-info-group i)) infos)) + + ;; Find the original locations of GROUPS in `gnus-group-list', and + ;; replace each one, in order, with a group from SORTED-GROUPS. + (dolist (i (sort (mapcar (lambda (g) + (seq-position gnus-group-list g)) + groups) + #'<)) + (setf (nth i gnus-group-list) + (pop sorted-groups))))) (defun gnus-group-sort-selected-groups-by-alphabet (&optional n reverse) "Sort the group buffer alphabetically by group name. diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el index 2f8a260bf13..ef07dcd23c0 100644 --- a/lisp/gnus/gnus-start.el +++ b/lisp/gnus/gnus-start.el @@ -583,12 +583,9 @@ Can be used to turn version control on or off." (defun gnus-subscribe-alphabetically (newgroup) "Subscribe new NEWGROUP and insert it in alphabetical order." - (let ((groups (cdr gnus-newsrc-alist)) - before) - (while (and (not before) groups) - (if (string< newgroup (caar groups)) - (setq before (caar groups)) - (setq groups (cdr groups)))) + (let ((before (seq-find (lambda (group) + (string< newgroup group)) + (cdr gnus-group-list)))) (gnus-subscribe-newsgroup newgroup before))) (defun gnus-subscribe-hierarchically (newgroup) @@ -618,15 +615,15 @@ It is inserted in hierarchical newsgroup order if subscribed. If not, it is killed." (if (gnus-y-or-n-p (format "Subscribe new newsgroup %s? " group)) (gnus-subscribe-hierarchically group) - (push group gnus-killed-list))) + (gnus-subscribe-killed group))) (defun gnus-subscribe-zombies (group) "Make the new GROUP into a zombie group." - (push group gnus-zombie-list)) + (cl-pushnew group gnus-zombie-list :test #'equal)) (defun gnus-subscribe-killed (group) "Make the new GROUP a killed group." - (push group gnus-killed-list)) + (cl-pushnew group gnus-killed-list :test #'equal)) (defun gnus-subscribe-newsgroup (newsgroup &optional next) "Subscribe new NEWSGROUP.