>From 56f4dacf5c1062b156df46778644e65378a9b4a2 Mon Sep 17 00:00:00 2001 From: Eric Abrahamsen Date: Wed, 17 Jul 2019 18:49:27 -0700 Subject: [PATCH] WIP on using gnus info accessors --- lisp/gnus/gnus-agent.el | 36 ++++++------ lisp/gnus/gnus-group.el | 80 +++++++++++++------------- lisp/gnus/gnus-int.el | 2 +- lisp/gnus/gnus-sieve.el | 2 +- lisp/gnus/gnus-start.el | 79 ++++++++++++++------------ lisp/gnus/gnus-sum.el | 49 +++++++--------- lisp/gnus/gnus.el | 122 ++++++++++++++++++++++++---------------- lisp/gnus/nndiary.el | 5 +- lisp/gnus/nndraft.el | 18 +++--- lisp/gnus/nnimap.el | 23 ++++---- lisp/gnus/nnir.el | 8 +-- lisp/gnus/nnmaildir.el | 10 ++-- lisp/gnus/nnmairix.el | 38 ++++++------- lisp/gnus/nnml.el | 4 +- lisp/gnus/nnvirtual.el | 17 +++--- 15 files changed, 252 insertions(+), 241 deletions(-) diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el index 1f25255278..a58a35df98 100644 --- a/lisp/gnus/gnus-agent.el +++ b/lisp/gnus/gnus-agent.el @@ -1212,22 +1212,21 @@ gnus-agent-synchronize-group-flags (marks (nth 2 action))) (dolist (mark marks) (cond ((eq mark 'read) - (gnus-info-set-read - info - (funcall (if (eq what 'add) - 'gnus-range-add - 'gnus-remove-from-range) - (gnus-info-read info) - range)) + (setf (gnus-info-read info) + (funcall (if (eq what 'add) + 'gnus-range-add + 'gnus-remove-from-range) + (gnus-info-read info) + range)) (gnus-get-unread-articles-in-group info (gnus-active (gnus-info-group info)))) ((memq mark '(tick)) (let ((info-marks (assoc mark (gnus-info-marks info)))) (unless info-marks - (gnus-info-set-marks - info (cons (setq info-marks (list mark)) - (gnus-info-marks info)))) + (setf (gnus-info-marks info) + (cons (setq info-marks (list mark)) + (gnus-info-marks info)))) (setcdr info-marks (funcall (if (eq what 'add) 'gnus-range-add @@ -1303,12 +1302,11 @@ gnus-agent-possibly-alter-active ;; file. (let ((read (gnus-info-read info))) - (gnus-info-set-read - info - (gnus-range-add - read - (list (cons (1+ agent-max) - (1- active-min)))))) + (setf (gnus-info-read info) + (gnus-range-add + read + (list (cons (1+ agent-max) + (1- active-min)))))) ;; Lie about the agent's local range for this group to ;; disable the set read each time this server is opened. @@ -2535,11 +2533,11 @@ gnus-agent-fetch-group-1 (when (cdr marked-arts) (setq marks (delq marked-arts (gnus-info-marks info))) - (gnus-info-set-marks info marks))))) + (setf (gnus-info-marks info) marks))))) (let ((read (gnus-info-read (or info (setq info (gnus-get-info group)))))) - (gnus-info-set-read - info (gnus-add-to-range read unfetched-articles))) + (setf (gnus-info-read info) + (gnus-add-to-range read unfetched-articles))) (gnus-group-update-group group t) (sit-for 0) diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index 8f5f5d66e4..0d3649120d 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el @@ -1423,7 +1423,7 @@ gnus-group-update-group-line (not (gnus-ephemeral-group-p group)) (gnus-dribble-enter (concat "(gnus-group-set-info '" - (gnus-prin1-to-string (nth 1 entry)) + (gnus-prin1-to-string (gnus-get-info group)) ")") (concat "^(gnus-group-set-info '(\"" (regexp-quote group) "\""))) (setq gnus-group-indentation (gnus-group-group-indentation)) @@ -1440,10 +1440,10 @@ gnus-group-insert-group-line-info (if entry (progn ;; (Un)subscribed group. - (setq info (nth 1 entry)) + (setq info (gnus-get-info group)) (gnus-group-insert-group-line group (gnus-info-level info) (gnus-info-marks info) - (or (car entry) t) (gnus-info-method info))) + (or (gnus-group-unread group) t) (gnus-info-method info))) ;; This group is dead. (gnus-group-insert-group-line group @@ -1457,7 +1457,7 @@ gnus-group-insert-group-line-info (gnus-method-simplify (gnus-find-method-for-group group)))))) (defun gnus-number-of-unseen-articles-in-group (group) - (let* ((info (nth 1 (gnus-group-entry group))) + (let* ((info (gnus-get-info group)) (marked (gnus-info-marks info)) (seen (cdr (assq 'seen marked))) (active (gnus-active group))) @@ -1595,15 +1595,15 @@ gnus-group-update-eval-form "Eval `car' of each element of LIST, and return the first that return t. Some value are bound so the form can use them." (when list - (let* ((entry (gnus-group-entry group)) + (let* ((unread (gnus-group-unread group)) (active (gnus-active group)) - (info (nth 1 entry)) + (info (gnus-get-info group)) (method (inline (gnus-server-get-method group (gnus-info-method info)))) (marked (gnus-info-marks info)) (env (list - (cons 'unread (if (numberp (car entry)) (car entry) 0)) + (cons 'unread (if (numberp unread) unread 0)) (cons 'total (if active (1+ (- (cdr active) (car active))) 0)) (cons 'mailp (apply 'append @@ -1676,7 +1676,7 @@ gnus-group-update-group (not (gnus-ephemeral-group-p group))) (gnus-dribble-enter (concat "(gnus-group-set-info '" - (gnus-prin1-to-string (nth 1 entry)) + (gnus-prin1-to-string (gnus-get-info group)) ")") (concat "^(gnus-group-set-info '(\"" (regexp-quote group) "\""))))) @@ -2752,7 +2752,9 @@ gnus-group-make-group (error "Group %s already exists" nname)) ;; Subscribe to the new group. (gnus-group-change-level - (setq info (list t nname gnus-level-default-subscribed nil nil meth)) + (setq info (list t (make-gnus-info + nname + gnus-level-default-subscribed nil nil meth))) gnus-level-default-subscribed gnus-level-killed (gnus-group-group-name) t) ;; Make it active. @@ -2958,9 +2960,9 @@ gnus-group-edit-group-done (if (or (not method) (gnus-server-equal gnus-select-method method)) - (gnus-group-real-name (car info)) + (gnus-group-real-name group) (gnus-group-prefixed-name - (gnus-group-real-name (car info)) method)) + (gnus-group-real-name group) method)) nil))) (when (and new-group (not (equal new-group group))) @@ -2973,11 +2975,11 @@ gnus-group-edit-group-done (setq info (copy-tree info)) (setcar info new-group) (unless (gnus-server-equal method "native") - (unless (nthcdr 3 info) + (unless (gnus-info-marks info) (nconc info (list nil nil))) - (unless (nthcdr 4 info) + (unless (gnus-info-method info) (nconc info (list nil))) - (gnus-info-set-method info method)) + (setf (gnus-info-method info) method)) (gnus-group-set-info info)) (gnus-group-update-group (or new-group group)) (gnus-group-position-point))) @@ -3531,17 +3533,17 @@ gnus-info-clear-data (gnus-undo-register `(progn (gnus-request-set-mark ,group ',action) - (gnus-info-set-marks ',info ',(gnus-info-marks info) t) - (gnus-info-set-read ',info ',(gnus-info-read info)) + (setf (gnus-info-marks ',info) ',(gnus-info-marks info) t) + (setf (gnus-info-read ',info) ',(gnus-info-read info)) (when (gnus-group-jump-to-group ,group) (gnus-get-unread-articles-in-group ',info ',(gnus-active group) t) (gnus-group-update-group-line)))) (setq action (mapcar (lambda (el) (list (nth 0 el) 'del (nth 2 el))) action)) (gnus-request-set-mark group action) - (gnus-info-set-read info nil) + (setf (gnus-info-read info) nil) (when (gnus-info-marks info) - (gnus-info-set-marks info nil)))) + (setf (gnus-info-marks info) nil)))) ;; Group catching up. @@ -3903,7 +3905,7 @@ gnus-group-yank-group (while (>= (cl-decf arg) 0) (when (not (setq info (pop gnus-list-of-killed-groups))) (error "No more newsgroups to yank")) - (push (setq group (nth 1 info)) out) + (push (setq group (gnus-info-group info)) out) ;; Find which newsgroup to insert this one before - search ;; backward until something suitable is found. If there are no ;; other newsgroups in this buffer, just make this newsgroup the @@ -4413,6 +4415,7 @@ gnus-group-browse-foreign-server (gnus-browse-foreign-server method)) (defun gnus-group-set-info (info &optional method-only-group part) + "Update status for group represented by INFO." (when (or info part) (let* ((entry (gnus-group-entry (or method-only-group (gnus-info-group info)))) @@ -4459,20 +4462,12 @@ gnus-group-set-info ;; can do the update. (if entry (progn - (setcar (nthcdr 1 entry) info) + (gnus-set-info (nthcdr 1 entry) info) (when (and (not (eq (car entry) t)) (gnus-active (gnus-info-group info))) - (setcar entry (length - (gnus-list-of-unread-articles (car info))))) - ;; The above `setcar' will only affect the hashtable, not - ;; the alist: update the alist separately, but only if - ;; it's been initialized. - (when gnus-newsrc-alist - (push info (cdr (setq gnus-newsrc-alist - (remove (assoc-string - (gnus-info-group info) - gnus-newsrc-alist) - gnus-newsrc-alist)))))) + (setf (gnus-group-unread (gnus-info-group info)) + (length + (gnus-list-of-unread-articles (car info)))))) (error "No such group: %s" (gnus-info-group info)))))) ;; Ad-hoc function for inserting data from a different newsrc.eld @@ -4497,20 +4492,23 @@ gnus-add-marked-articles (let ((info (or info (gnus-get-info group))) marked m) (or (not info) - (and (not (setq marked (nthcdr 3 info))) + (and (not (setq marked (gnus-info-marks info))) (or (null articles) - (setcdr (nthcdr 2 info) - (list (list (cons type (gnus-compress-sequence - articles t))))))) - (and (not (setq m (assq type (car marked)))) + ;; Group had no marks at all, set unconditionally. + (setf (gnus-info-marks info) + (list (cons type (gnus-compress-sequence + articles t)))))) + (and (not (setq m (assq type marked))) (or (null articles) - (setcar marked - (cons (cons type (gnus-compress-sequence articles t) ) - (car marked))))) + ;; Group had no marks of TYPE. + (setf (gnus-info-marks info) + (cons (cons type (gnus-compress-sequence articles t)) + marked)))) (if force + ;; Replace (or remove) all marks of TYPE. (if (null articles) - (setcar (nthcdr 3 info) - (assq-delete-all type (car marked))) + (setf (gnus-info-marks info) + (assq-delete-all type marked)) (setcdr m (gnus-compress-sequence articles t))) (setcdr m (gnus-compress-sequence (sort (nconc (gnus-uncompress-range (cdr m)) diff --git a/lisp/gnus/gnus-int.el b/lisp/gnus/gnus-int.el index 0abbfe6720..a21bc25840 100644 --- a/lisp/gnus/gnus-int.el +++ b/lisp/gnus/gnus-int.el @@ -727,7 +727,7 @@ gnus-request-marks (let* ((range (if (= min 2) 1 (cons 1 (1- min)))) (read (gnus-info-read info)) (new-read (gnus-range-add read (list range)))) - (gnus-info-set-read info new-read))) + (setf (gnus-info-read info) new-read))) info))))) (defun gnus-request-expire-articles (articles group &optional force) diff --git a/lisp/gnus/gnus-sieve.el b/lisp/gnus/gnus-sieve.el index fc0bf3098b..5edd6f5f7a 100644 --- a/lisp/gnus/gnus-sieve.el +++ b/lisp/gnus/gnus-sieve.el @@ -128,7 +128,7 @@ gnus-sieve-article-add-rule (info (gnus-get-info gnus-newsgroup-name))) (if (null rule) (error "Could not guess rule for article") - (gnus-info-set-params info (cons rule (gnus-info-params info))) + (push rule (gnus-info-params info)) (message "Added rule in group %s for article: %s" gnus-newsgroup-name rule))))) diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el index e142c438ee..70e63188c9 100644 --- a/lisp/gnus/gnus-start.el +++ b/lisp/gnus/gnus-start.el @@ -1295,7 +1295,7 @@ gnus-group-change-level (t (when (and (>= level gnus-level-zombie) entry) - (remhash (car (nth 1 entry)) gnus-newsrc-hashtb) + (remhash group gnus-newsrc-hashtb) (setq gnus-group-list (remove group gnus-group-list)) (setq gnus-newsrc-alist (delq (assoc group gnus-newsrc-alist) gnus-newsrc-alist))))) @@ -1323,7 +1323,7 @@ gnus-group-change-level ;; It was alive, and it is going to stay alive, so we ;; just change the level and don't change any pointers or ;; hash table entries. - (setcar (cdadr entry) level) + (setf (gnus-info-level (nth 1 entry)) level) (if (listp entry) (setq info (cdr entry) num (car entry)) @@ -1577,7 +1577,7 @@ gnus-get-unread-articles-in-group ;; Set the number of unread articles. (when (and info (gnus-group-entry (gnus-info-group info))) - (setcar (gnus-group-entry (gnus-info-group info)) num)) + (setf (gnus-group-unread (gnus-info-group info)) num)) num))) ;; Go though `gnus-newsrc-alist' and compare with `gnus-active-hashtb' @@ -1603,7 +1603,7 @@ gnus-get-unread-articles (gnus-agent-article-local-times 0) (archive-method (gnus-server-to-method "archive")) infos info group active method cmethod - method-type method-group-list entry) + method-type method-group-list) (gnus-message 6 "Checking new news...") (while newsrc @@ -1650,8 +1650,8 @@ gnus-get-unread-articles ;; It leads `(gnus-group-unread group)' to return t. See also ;; `gnus-group-prepare-flat'. (unless active - (when (setq entry (gnus-group-entry group)) - (setcar entry t))))) + (when (gnus-group-entry group) + (setf (gnus-group-unread group) t))))) ;; Sort the methods based so that the primary and secondary ;; methods come first. This is done for legacy reasons to try to @@ -1824,17 +1824,17 @@ gnus-make-hashtable-from-newsrc-alist gnus-newsrc-alist (cons (list "dummy.group" 0 nil) alist)))) (while alist - (setq info (car alist)) + (setq info (apply #'make-gnus-info (car alist))) ;; Make the same select-methods identical Lisp objects. (when (setq method (gnus-info-method info)) (if (setq rest (member method methods)) - (gnus-info-set-method info (car rest)) + (setf (gnus-info-method info) (car rest)) (push method methods))) ;; Check for encoded group names and decode them. - (when (string-match-p "[^[:ascii:]]" (setq gname (car info))) + (when (string-match-p "[^[:ascii:]]" (setq gname (gnus-info-group info))) (let ((decoded (gnus-group-decoded-name gname))) (setf gname decoded - (car info) decoded))) + (gnus-info-group info) decoded))) ;; Check for duplicates. (if (gethash gname gnus-newsrc-hashtb) ;; Remove this entry from the alist. @@ -1879,9 +1879,9 @@ gnus-parse-active (defun gnus-make-articles-unread (group articles) "Mark ARTICLES in GROUP as unread." - (let* ((info (nth 1 (or (gnus-group-entry group) - (gnus-group-entry - (gnus-group-real-name group))))) + (let* ((info (or (gnus-get-info group) + (gnus-get-info + (gnus-group-real-name group)))) (ranges (gnus-info-read info)) news article) (while articles @@ -1890,8 +1890,8 @@ gnus-make-articles-unread (push article news))) (when news ;; Enter this list into the group info. - (gnus-info-set-read - info (gnus-remove-from-range (gnus-info-read info) (nreverse news))) + (setf (gnus-info-read info) + (gnus-remove-from-range (gnus-info-read info) (nreverse news))) ;; Set the number of unread articles in gnus-newsrc-hashtb. (gnus-get-unread-articles-in-group info (gnus-active group)) @@ -1901,9 +1901,8 @@ gnus-make-articles-unread (defun gnus-make-ascending-articles-unread (group articles) "Mark ascending ARTICLES in GROUP as unread." - (let* ((entry (or (gnus-group-entry group) - (gnus-group-entry (gnus-group-real-name group)))) - (info (nth 1 entry)) + (let* ((info (or (gnus-get-info group) + (gnus-get-info (gnus-group-real-name group)))) (ranges (gnus-info-read info)) (r ranges) modified) @@ -1911,7 +1910,7 @@ gnus-make-ascending-articles-unread (while articles (let ((article (pop articles))) ; get the next article to remove from ranges (while (let ((range (car ranges))) ; note the current range - (if (atom range) ; single value range + (if (atom range) ; single value range (cond ((not range) ;; the articles extend past the end of the ranges ;; OK - I'm done @@ -1958,7 +1957,7 @@ gnus-make-ascending-articles-unread (when (eq modified 'remove-null) (setq r (delq nil r))) ;; Enter this list into the group info. - (gnus-info-set-read info r) + (setf (gnus-info-read info) r) ;; Set the number of unread articles in gnus-newsrc-hashtb. (gnus-get-unread-articles-in-group info (gnus-active group)) @@ -2362,12 +2361,11 @@ gnus-convert-old-ticks (setq dormant (cdr (assq 'dormant marks)) ticked (cdr (assq 'tick marks))) (when (or dormant ticked) - (gnus-info-set-read - info - (gnus-add-to-range - (gnus-info-read info) - (nconc (gnus-uncompress-range dormant) - (gnus-uncompress-range ticked))))))))) + (setf (gnus-info-read info) + (gnus-add-to-range + (gnus-info-read info) + (nconc (gnus-uncompress-range dormant) + (gnus-uncompress-range ticked))))))))) (defun gnus-load (file) "Load FILE, but in such a way that read errors can be reported." @@ -2438,9 +2436,9 @@ gnus-read-old-newsrc-el-file (while (setq group (pop newsrc)) (if (setq info (gnus-get-info (car group))) (progn - (gnus-info-set-read info (cddr group)) - (gnus-info-set-level - info (if (nth 1 group) gnus-level-default-subscribed + (setf (gnus-info-read info) (cddr group)) + (setf (gnus-info-level info) + (if (nth 1 group) gnus-level-default-subscribed gnus-level-default-unsubscribed)) (push info gnus-newsrc-alist)) (push (setq info @@ -2451,10 +2449,10 @@ gnus-read-old-newsrc-el-file gnus-newsrc-alist)) ;; Copy marks into info. (when (setq m (assoc (car group) marked)) - (unless (nthcdr 3 info) + (unless (gnus-info-marks info) (nconc info (list nil))) - (gnus-info-set-marks - info (list (cons 'tick (gnus-compress-sequence + (setf (gnus-info-marks info) + (list (cons 'tick (gnus-compress-sequence (sort (cdr m) '<) t)))))) (setq newsrc killed) (while newsrc @@ -2609,7 +2607,7 @@ gnus-newsrc-to-gnus-format ;; There is an entry for this file in ;; `gnus-newsrc-hashtb'. (progn - (gnus-info-set-read info (nreverse reads)) + (setf (gnus-info-read info) (nreverse reads)) ;; We update the level very gently. In fact, we ;; only change it if there's been a status change ;; from subscribed to unsubscribed, or vice versa. @@ -2621,7 +2619,7 @@ gnus-newsrc-to-gnus-format (1+ gnus-level-default-unsubscribed)))) ((and (> level gnus-level-subscribed) subscribed) (setq level gnus-level-default-subscribed))) - (gnus-info-set-level info level)) + (setf (gnus-info-level info) level)) ;; This is a new group. (setq info (list group (if subscribed @@ -2645,7 +2643,7 @@ gnus-newsrc-to-gnus-format (prev gnus-newsrc-alist) entry mentry) (while rc - (or (null (nth 4 (car rc))) ; It's a native group. + (or (null (gnus-info-method (car rc))) ; It's a native group. (assoc (caar rc) newsrc) ; It's already in the alist. (if (setq entry (assoc (caar prev) newsrc)) (setcdr (setq mentry (memq entry newsrc)) @@ -2903,7 +2901,14 @@ gnus-gnus-to-quick-newsrc-format ;; `gnus-read-newsrc-el-file' into a conversion routine. (gnus-newsrc-alist (mapcar (lambda (info) - (cons (encode-coding-string (car info) 'utf-8-emacs) + (let ((i 5)) + ;; Don't write unnecessary nils to disk. + (while (and (> i 2) + (not (nth i info))) + (when (nthcdr (cl-decf i) info) + (setcdr (nthcdr i info) nil)))) + (cons (encode-coding-string + (gnus-info-group info) 'utf-8-emacs) (cdr info))) gnus-newsrc-alist)) (gnus-topic-alist @@ -2952,7 +2957,7 @@ gnus-gnus-to-newsrc-format (insert gnus-newsrc-options)) ;; Write subscribed and unsubscribed. (dolist (g-name groups) - (setq info (nth 1 (gnus-group-entry g-name))) + (setq info (gnus-get-info g-name)) ;; Maybe don't write foreign groups to .newsrc. (when (or (null (setq method (gnus-info-method info))) (equal method "native") diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index f21bc7584e..75bc9acb66 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -6172,18 +6172,7 @@ gnus-update-marks (gnus-request-set-mark gnus-newsgroup-name delta-marks)) ;; Enter these new marks into the info of the group. - (if (nthcdr 3 info) - (setcar (nthcdr 3 info) newmarked) - ;; Add the marks lists to the end of the info. - (when newmarked - (setcdr (nthcdr 2 info) (list newmarked)))) - - ;; Cut off the end of the info if there's nothing else there. - (let ((i 5)) - (while (and (> i 2) - (not (nth i info))) - (when (nthcdr (cl-decf i) info) - (setcdr (nthcdr i info) nil))))))) + (setf (gnus-info-marks info) newmarked)))) (defun gnus-set-mode-line (where) "Set the mode line of the article or summary buffers. @@ -6278,7 +6267,7 @@ gnus-create-xref-hashtb (defun gnus-mark-xrefs-as-read (from-newsgroup headers unreads) "Look through all the headers and mark the Xrefs as read." (let ((virtual (gnus-virtual-group-p from-newsgroup)) - info xref-hashtb method nth4) + info xref-hashtb method tmp-method) (with-current-buffer gnus-group-buffer (when (setq xref-hashtb (gnus-create-xref-hashtb from-newsgroup headers unreads)) @@ -6288,17 +6277,18 @@ gnus-mark-xrefs-as-read ;; Dead groups are not updated. (and (prog1 (setq info (gnus-get-info group)) - (when (stringp (setq nth4 (gnus-info-method info))) - (setq nth4 (gnus-server-to-method nth4)))) + (when (stringp (setq tmp-method (gnus-info-method info))) + (setq tmp-method (gnus-server-to-method tmp-method)))) ;; Only do the xrefs if the group has the same ;; select method as the group we have just read. (or (gnus-methods-equal-p - nth4 (gnus-find-method-for-group from-newsgroup)) + tmp-method (gnus-find-method-for-group from-newsgroup)) virtual - (equal nth4 (setq method (gnus-find-method-for-group - from-newsgroup))) - (and (equal (car nth4) (car method)) - (equal (nth 1 nth4) (nth 1 method)))) + (equal tmp-method + (setq method (gnus-find-method-for-group + from-newsgroup))) + (and (equal (car tmp-method) (car method)) + (equal (nth 1 tmp-method) (nth 1 method)))) gnus-use-cross-reference (or (not (eq gnus-use-cross-reference t)) virtual @@ -6310,7 +6300,7 @@ gnus-mark-xrefs-as-read (defun gnus-compute-read-articles (group articles) (let* ((entry (gnus-group-entry group)) - (info (nth 1 entry)) + (info (gnus-get-info entry)) (active (gnus-active group)) ninfo) (when entry @@ -6347,7 +6337,7 @@ gnus-group-make-articles-read "Update the info of GROUP to say that ARTICLES are read." (let* ((num 0) (entry (gnus-group-entry group)) - (info (nth 1 entry)) + (info (gnus-get-info entry)) (active (gnus-active group)) (set-marks (gnus-method-option-p @@ -6367,7 +6357,7 @@ gnus-group-make-articles-read (gnus-undo-register `(progn (gnus-info-set-marks ',info ',(gnus-info-marks info) t) - (gnus-info-set-read ',info ',(gnus-info-read info)) + (setf (gnus-info-read ',info) ',(gnus-info-read info)) (gnus-get-unread-articles-in-group ',info (gnus-active ,group)) (when ,set-marks (gnus-request-set-mark @@ -6375,7 +6365,7 @@ gnus-group-make-articles-read (gnus-group-jump-to-group ,group) (gnus-group-update-group ,group t)))) ;; Add the read articles to the range. - (gnus-info-set-read info range) + (setf (gnus-info-read info) range) (when set-marks (gnus-request-set-mark group (list (list range 'add '(read))))) ;; Then we have to re-compute how many unread @@ -6395,7 +6385,7 @@ gnus-group-make-articles-read (setq range (cdr range))) (setq num (- (cdr active) num)))) ;; Update the number of unread articles. - (setcar entry num) + (setf (gnus-group-unread group) num) ;; Update the group buffer. (unless (gnus-ephemeral-group-p group) (gnus-group-update-group group t)))))) @@ -10283,8 +10273,8 @@ gnus-summary-move-article (when (and (not (memq article gnus-newsgroup-unreads)) (cdr art-group)) (push 'read to-marks) - (gnus-info-set-read - info (gnus-add-to-range (gnus-info-read info) + (setf (gnus-info-read info) + (gnus-add-to-range (gnus-info-read info) (list (cdr art-group))))) ;; See whether the article is to be put in the cache. @@ -12894,15 +12884,16 @@ gnus-update-read-articles (set-buffer gnus-group-buffer) (gnus-undo-register `(progn + ;;FIXME: A better way of ensuring info completness? (gnus-info-set-marks ',info ',(gnus-info-marks info) t) - (gnus-info-set-read ',info ',(gnus-info-read info)) + (setf (gnus-info-read ',info) ',(gnus-info-read info)) (gnus-group-jump-to-group ,group) (gnus-get-unread-articles-in-group ',info (gnus-active ,group)) (gnus-group-update-group ,group t) ,setmarkundo)))) ;; Enter this list into the group info. - (gnus-info-set-read info read) + (setf (gnus-info-read info) read) ;; Set the number of unread articles in gnus-newsrc-hashtb. (gnus-get-unread-articles-in-group info (gnus-active group)) t)))) diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index 0673ac15f6..392a4e8812 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el @@ -2815,20 +2815,37 @@ gnus-set-active "Set GROUP's active info." `(puthash ,group ,active gnus-active-hashtb)) -;; Info access macros. - -(defmacro gnus-info-group (info) - `(nth 0 ,info)) -(defmacro gnus-info-rank (info) - `(nth 1 ,info)) -(defmacro gnus-info-read (info) - `(nth 2 ,info)) -(defmacro gnus-info-marks (info) - `(nth 3 ,info)) -(defmacro gnus-info-method (info) - `(nth 4 ,info)) -(defmacro gnus-info-params (info) - `(nth 5 ,info)) +;; Info definition. + +(cl-defstruct (gnus-info + (:copier nil) + (:constructor make-gnus-info + (group rank read &optional marks method params)) + (:type list)) + "A structure holding information about a Gnus group." + (group "" + :type string + :documentation "The group name of this info.") + (rank `,gnus-level-default-subscribed + :type (or integer cons) + :documentation "The rank of this group. Either a single + integer indicating the level of subscribedness, or a cons + of (LEVEL . SCORE).") + (read nil + :type list + :documentation "A range of read articles in this group.") + (marks nil + :type list + :documentation "An alist of marks (as symbols) mapped to + ranges of articles that have those marks.") + (method nil + :type list + :documentation "This group's server method. Typically + a list of (TYPE ADDRESS), where TYPE is a backend + symbol and ADDRESS is a string adress.") + (params nil + :type list + :documentation "An alist of group parameters.")) (defmacro gnus-info-level (info) `(let ((rank (gnus-info-rank ,info))) @@ -2839,49 +2856,55 @@ gnus-info-score `(let ((rank (gnus-info-rank ,info))) (or (and (consp rank) (cdr rank)) 0))) +;; These setters are mostly here for backwards compatibility. + (defmacro gnus-info-set-group (info group) - `(setcar ,info ,group)) + `(setf (gnus-info-group ,info) ,group)) + (defmacro gnus-info-set-rank (info rank) - `(setcar (nthcdr 1 ,info) ,rank)) + `(setf (gnus-info-rank ,info) ,rank)) + (defmacro gnus-info-set-read (info read) - `(setcar (nthcdr 2 ,info) ,read)) -(defmacro gnus-info-set-marks (info marks &optional extend) - (if extend - `(gnus-info-set-entry ,info ,marks 3) - `(setcar (nthcdr 3 ,info) ,marks))) -(defmacro gnus-info-set-method (info method &optional extend) - (if extend - `(gnus-info-set-entry ,info ,method 4) - `(setcar (nthcdr 4 ,info) ,method))) -(defmacro gnus-info-set-params (info params &optional extend) - (if extend - `(gnus-info-set-entry ,info ,params 5) - `(setcar (nthcdr 5 ,info) ,params))) - -(defun gnus-info-set-entry (info entry number) - ;; Extend the info until we have enough elements. - (while (<= (length info) number) - (nconc info (list nil))) - ;; Set the entry. - (setcar (nthcdr number info) entry)) + `(setf (gnus-info-read ,info) ,read)) + +(defmacro gnus-info-set-marks (info marks &optional _extend) + `(setf (gnus-info-marks ,info) ,marks)) + +(defmacro gnus-info-set-method (info method &optional _extend) + `(setf (gnus-info-method ,info) ,method)) + +(defmacro gnus-info-set-params (info params &optional _extend) + `(setf (gnus-info-params ,info) ,params)) (defmacro gnus-info-set-level (info level) - `(let ((rank (cdr ,info))) - (if (consp (car rank)) - (setcar (car rank) ,level) - (setcar rank ,level)))) + `(let ((rank (gnus-info-rank ,info))) + (if (consp rank) + (setcar (gnus-info-rank ,info) ,level) + (setf (gnus-info-rank ,info) ,level)))) + (defmacro gnus-info-set-score (info score) - `(let ((rank (cdr ,info))) - (if (consp (car rank)) - (setcdr (car rank) ,score) - (setcar rank (cons (car rank) ,score))))) + `(let ((rank (gnus-info-rank ,info))) + (if (consp rank) + (setcdr (gnus-info-rank ,info) ,score) + (setf (gnus-info-rank ,info) (cons rank ,score))))) (defmacro gnus-get-info (group) `(nth 1 (gethash ,group gnus-newsrc-hashtb))) (defun gnus-set-info (group info) - (setcdr (gethash group gnus-newsrc-hashtb) - (list info))) + (let ((entry (cdr (gethash group gnus-newsrc-hashtb)))) + ;; Set individual elements of the info so as not to break object + ;; reference. + (setf (gnus-info-rank entry) + (gnus-info-rank info)) + (setf (gnus-info-read entry) + (gnus-info-read info)) + (setf (gnus-info-marks entry) + (gnus-info-marks info)) + (setf (gnus-info-method entry) + (gnus-info-method info)) + (setf (gnus-info-params entry) + (gnus-info-params info)))) ;;; @@ -3689,7 +3712,7 @@ gnus-group-set-parameter (setq new-params (append new-params (list (car old-params))))) (setq old-params (cdr old-params))) (if (listp group) - (gnus-info-set-params info new-params t) + (setf (gnus-info-params info) new-params) (gnus-group-set-info new-params (gnus-info-group info) 'params)))))) (defun gnus-group-remove-parameter (group name) @@ -3704,14 +3727,15 @@ gnus-group-remove-parameter (setq params (delq name params)) (while (assq name params) (gnus-alist-pull name params)) - (gnus-info-set-params info params)))))) + (setf (gnus-info-params info) params)))))) (defun gnus-group-add-score (group &optional score) "Add SCORE to the GROUP score. If SCORE is nil, add 1 to the score of GROUP." (let ((info (gnus-get-info group))) (when info - (gnus-info-set-score info (+ (gnus-info-score info) (or score 1)))))) + (setf (gnus-info-score info) + (+ (gnus-info-score info) (or score 1)))))) (defun gnus-short-group-name (group &optional levels) "Collapse GROUP name LEVELS. diff --git a/lisp/gnus/nndiary.el b/lisp/gnus/nndiary.el index f79d8f1707..88bb5651e2 100644 --- a/lisp/gnus/nndiary.el +++ b/lisp/gnus/nndiary.el @@ -795,8 +795,9 @@ nndiary-request-update-info (kill-buffer buf)) (setq unread (sort unread '<)) (and unread - (gnus-info-set-read info (gnus-update-read-articles - (gnus-info-group info) unread t))) + (setf (gnus-info-read info) + (gnus-update-read-articles + (gnus-info-group info) unread t))) )) (run-hook-with-args 'nndiary-request-update-info-functions (gnus-info-group info)) diff --git a/lisp/gnus/nndraft.el b/lisp/gnus/nndraft.el index bc475ee295..cc9923164a 100644 --- a/lisp/gnus/nndraft.el +++ b/lisp/gnus/nndraft.el @@ -147,17 +147,17 @@ nndraft-request-restore-buffer (deffoo nndraft-request-update-info (group info &optional server) (nndraft-possibly-change-group group) - (gnus-info-set-read - info - (gnus-update-read-articles (gnus-group-prefixed-name group '(nndraft "")) - (nndraft-articles) t)) - (let ((marks (nth 3 info))) + (setf (gnus-info-read info) + (gnus-update-read-articles + (gnus-group-prefixed-name group '(nndraft "")) + (nndraft-articles) t)) + (let ((marks (gnus-info-marks info))) (when marks ;; Nix out all marks except the `unsend'-able article marks. - (setcar (nthcdr 3 info) - (if (assq 'unsend marks) - (list (assq 'unsend marks)) - nil)))) + (setf (gnus-info-marks info) + (if (assq 'unsend marks) + (list (assq 'unsend marks)) + nil)))) t) (defun nndraft-generate-headers () diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el index 856ac75cd6..98be27fc74 100644 --- a/lisp/gnus/nnimap.el +++ b/lisp/gnus/nnimap.el @@ -1620,7 +1620,7 @@ nnimap-update-info read))) (when (or (not (listp permanent-flags)) (memq '%Seen permanent-flags)) - (gnus-info-set-read info read)) + (setf (gnus-info-read info) read)) ;; Update the marks. (setq marks (gnus-info-marks info)) (dolist (type (cdr nnimap-mark-alist)) @@ -1663,7 +1663,7 @@ nnimap-update-info (if old-unexists (setcdr old-unexists unexists) (push (cons 'unexist unexists) marks))) - (gnus-info-set-marks info marks t)))) + (setf (gnus-info-marks info) marks)))) ;; Tell Gnus whether there are any \Recent messages in any of ;; the groups. (let ((recent (cdr (assoc '%Recent flags)))) @@ -1680,14 +1680,13 @@ nnimap-update-info (defun nnimap-update-qresync-info (info existing vanished flags) ;; Add all the vanished articles to the list of read articles. - (gnus-info-set-read - info - (gnus-add-to-range - (gnus-add-to-range - (gnus-range-add (gnus-info-read info) - vanished) - (cdr (assq '%Flagged flags))) - (cdr (assq '%Seen flags)))) + (setf (gnus-info-read info) + (gnus-add-to-range + (gnus-add-to-range + (gnus-range-add (gnus-info-read info) + vanished) + (cdr (assq '%Flagged flags))) + (cdr (assq '%Seen flags)))) (let ((marks (gnus-info-marks info))) (dolist (type (cdr nnimap-mark-alist)) (let ((ticks (assoc (car type) marks)) @@ -1707,7 +1706,7 @@ nnimap-update-qresync-info (gnus-sorted-complement existing new-marks)))) (when ticks (push (cons (car type) ticks) marks)) - (gnus-info-set-marks info marks t)))) + (setf (gnus-info-marks info) marks)))) ;; Add vanished to the list of unexisting articles. (when vanished (let* ((old-unexists (assq 'unexist marks)) @@ -1715,7 +1714,7 @@ nnimap-update-qresync-info (if old-unexists (setcdr old-unexists unexists) (push (cons 'unexist unexists) marks))) - (gnus-info-set-marks info marks t)))) + (setf (gnus-info-marks info) marks)))) (defun nnimap-imap-ranges-to-gnus-ranges (irange) (if (zerop (length irange)) diff --git a/lisp/gnus/nnir.el b/lisp/gnus/nnir.el index 7cb2d1615a..45fbadf23c 100644 --- a/lisp/gnus/nnir.el +++ b/lisp/gnus/nnir.el @@ -874,8 +874,8 @@ nnir-request-set-mark (deffoo nnir-request-update-info (group info &optional server) (nnir-possibly-change-group group server) ;; clear out all existing marks. - (gnus-info-set-marks info nil) - (gnus-info-set-read info nil) + (setf (gnus-info-marks info) nil) + (setf (gnus-info-read info) nil) (let ((group (gnus-group-guess-full-name-from-command-method group)) (articles-by-group (nnir-categorize @@ -889,8 +889,8 @@ nnir-request-update-info (group-info (gnus-get-info (car group-articles))) (marks (gnus-info-marks group-info)) (read (gnus-info-read group-info))) - (gnus-info-set-read - info + (setf + (gnus-info-read info) (gnus-add-to-range (gnus-info-read info) (delq nil diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el index 0133fc6ce2..fdb487d076 100644 --- a/lisp/gnus/nnmaildir.el +++ b/lisp/gnus/nnmaildir.el @@ -1000,8 +1000,8 @@ nnmaildir-request-update-info pgname (nnmaildir--pgname nnmaildir--cur-server gname) flist (nnmaildir--grp-flist group)) (when (zerop (nnmaildir--grp-count group)) - (gnus-info-set-read info nil) - (gnus-info-set-marks info nil 'extend) + (setf (gnus-info-read info) nil + (gnus-info-marks info) nil) (throw 'return info)) (setq old-marks (cons 'read (gnus-info-read info)) old-marks (cons old-marks (gnus-info-marks info)) @@ -1083,9 +1083,9 @@ nnmaildir-request-update-info (setq ranges (gnus-add-to-range ranges (sort article-list '<))))) (if (eq mark 'read) (setq read ranges) (if ranges (setq marks (cons (cons mark ranges) marks))))) - (gnus-info-set-read info (gnus-range-add read missing)) - (gnus-info-set-marks info marks 'extend) - (setf (nnmaildir--grp-mmth group) new-mmth) + (setf (gnus-info-read info) (gnus-range-add read missing) + (gnus-info-marks info) marks + (nnmaildir--grp-mmth group) new-mmth) info))) (defun nnmaildir-request-group (gname &optional server fast _info) diff --git a/lisp/gnus/nnmairix.el b/lisp/gnus/nnmairix.el index 6c5502ac3d..722cb95306 100644 --- a/lisp/gnus/nnmairix.el +++ b/lisp/gnus/nnmairix.el @@ -711,29 +711,27 @@ nnmairix-request-marks (nnimap-request-update-info-internal folder folderinfo nnmairix-backend-server) (nnmairix-call-backend "request-update-info" folder folderinfo nnmairix-backend-server)) ;; set range of read articles - (gnus-info-set-read - info - (if docorr - (nnmairix-map-range - `(lambda (x) (+ x ,(cadr corr))) - (gnus-info-read folderinfo)) - (gnus-info-read folderinfo))) + (setf (gnus-info-read info) + (if docorr + (nnmairix-map-range + `(lambda (x) (+ x ,(cadr corr))) + (gnus-info-read folderinfo)) + (gnus-info-read folderinfo))) ;; set other marks - (gnus-info-set-marks - info - (if docorr - (mapcar (lambda (cur) - (cons - (car cur) - (nnmairix-map-range - `(lambda (x) (+ x ,(cadr corr))) - (list (cadr cur))))) - (gnus-info-marks folderinfo)) - (gnus-info-marks folderinfo)))) + (setf (gnus-info-marks info) + (if docorr + (mapcar (lambda (cur) + (cons + (car cur) + (nnmairix-map-range + `(lambda (x) (+ x ,(cadr corr))) + (list (cadr cur))))) + (gnus-info-marks folderinfo)) + (gnus-info-marks folderinfo)))) (when (eq readmarks 'unread) - (gnus-info-set-read info nil)) + (setf (gnus-info-read info) nil)) (when (eq readmarks 'read) - (gnus-info-set-read info (gnus-active qualgroup)))) + (setf (gnus-info-read info) (gnus-active qualgroup)))) t) (nnoo-define-skeleton nnmairix) diff --git a/lisp/gnus/nnml.el b/lisp/gnus/nnml.el index 302589bd6d..8d8d5ae83a 100644 --- a/lisp/gnus/nnml.el +++ b/lisp/gnus/nnml.el @@ -1067,7 +1067,7 @@ nnml-request-compact-group (when (gnus-member-of-range old-number read) (setq read (gnus-remove-from-range read (list old-number))) (setq read (gnus-add-to-range read (list new-number)))) - (gnus-info-set-read info read)) + (setf (gnus-info-read info) read)) ;; 2 b/ marked articles: (let ((oldmarks (gnus-info-marks info)) mark newmarks) @@ -1080,7 +1080,7 @@ nnml-request-compact-group (setcdr mark (gnus-add-to-range (cdr mark) (list new-number)))) (push mark newmarks)) - (gnus-info-set-marks info newmarks)) + (setf (gnus-info-marks info) newmarks)) ;; 3/ Update the NOV entry for this article: (unless nnml-nov-is-evil (with-current-buffer (nnml-open-nov group) diff --git a/lisp/gnus/nnvirtual.el b/lisp/gnus/nnvirtual.el index 25f3413fcd..0a4d33cfab 100644 --- a/lisp/gnus/nnvirtual.el +++ b/lisp/gnus/nnvirtual.el @@ -307,11 +307,9 @@ nnvirtual-request-update-info ;; Install the precomputed lists atomically, so the virtual group ;; is not left in a half-way state in case of C-g. (gnus-atomic-progn - (setcar (cddr info) nnvirtual-mapping-reads) - (if (nthcdr 3 info) - (setcar (nthcdr 3 info) nnvirtual-mapping-marks) - (when nnvirtual-mapping-marks - (setcdr (nthcdr 2 info) (list nnvirtual-mapping-marks)))) + (setf (gnus-info-read info) nnvirtual-mapping-reads) + (when nnvirtual-mapping-marks + (setf (gnus-info-marks info) nnvirtual-mapping-marks)) (setq nnvirtual-info-installed t)) t)) @@ -463,11 +461,10 @@ nnvirtual-update-read-and-marked (dolist (group nnvirtual-component-groups) (when (and (setq info (gnus-get-info group)) (gnus-info-marks info)) - (gnus-info-set-marks - info - (if (assq 'score (gnus-info-marks info)) - (list (assq 'score (gnus-info-marks info))) - nil)))) + (setf (gnus-info-marks info) + (if (assq 'score (gnus-info-marks info)) + (list (assq 'score (gnus-info-marks info))) + nil)))) ;; Ok, currently type-marks is an assq list with keys of a mark type, ;; with data of an assq list with keys of component group names -- 2.23.0