(defun gnus-update-read-articles (group unread &optional compute) "Update the list of read articles in GROUP." (let* ((active (or gnus-newsgroup-active (gnus-active group))) (entry (gnus-gethash group gnus-newsrc-hashtb)) (info (nth 2 entry)) (prev 1) (unread (sort (copy-sequence unread) '<)) read) (if (or (not info) (not active)) ;; There is no info on this group if it was, in fact, ;; killed. Gnus stores no information on killed groups, so ;; there's nothing to be done. ;; One could store the information somewhere temporarily, ;; perhaps... Hmmm... () ;; Remove any negative articles numbers. (while (and unread (< (car unread) 0)) (setq unread (cdr unread))) ;; Remove any expired article numbers (while (and unread (< (car unread) (car active))) (setq unread (cdr unread))) ;; Compute the ranges of read articles by looking at the list of ;; unread articles. (while unread (when (/= (car unread) prev) (push (if (= prev (1- (car unread))) prev (cons prev (1- (car unread)))) read)) (setq prev (1+ (car unread))) (setq unread (cdr unread))) (when (<= prev (cdr active)) (push (cons prev (cdr active)) read)) (setq read (if (> (length read) 1) (nreverse read) read)) (if compute read (save-excursion (set-buffer gnus-group-buffer) (gnus-undo-register `(progn (gnus-info-set-marks ',info ',(gnus-info-marks info) t) (gnus-info-set-read ',info ',(gnus-info-read info)) (gnus-get-unread-articles-in-group ',info (gnus-active ,group)) (gnus-group-update-group ,group t)))) ;; Propagate the read marks to the backend. (if (gnus-check-backend-function 'request-set-mark group) (let ((del (gnus-remove-from-range (gnus-info-read info) read)) (add (gnus-remove-from-range read (gnus-info-read info)))) (when (or add del) (gnus-request-set-mark group (delq nil (list (if add (list add 'add '(read))) (if del (list del 'del '(read))))))))) ;; Enter this list into the group info. (gnus-info-set-read info read) ;; Set the number of unread articles in gnus-newsrc-hashtb. (gnus-get-unread-articles-in-group info (gnus-active group)) t))))