Function: nnimap-update-info

nnimap-update-info is a byte-compiled function defined in nnimap.el.gz.

Signature

(nnimap-update-info INFO MARKS)

Source Code

;; Defined in /usr/src/emacs/lisp/gnus/nnimap.el.gz
(defun nnimap-update-info (info marks)
  (cl-destructuring-bind (existing flags high low uidnext start-article
				   permanent-flags uidvalidity
				   vanished highestmodseq)
      marks
    (cond
     ;; Ignore groups with no UIDNEXT/marks.  This happens for
     ;; completely empty groups.
     ((and (not existing)
	   (not uidnext))
      (let ((active (cdr (assq 'active (gnus-info-params info)))))
	(when active
	  (gnus-set-active (gnus-info-group info) active))))
     ;; We have a mismatch between the old and new UIDVALIDITY
     ;; identifiers, so we have to re-request the group info (the next
     ;; time).  This virtually never happens.
     ((let ((old-uidvalidity
	     (cdr (assq 'uidvalidity (gnus-info-params info)))))
	(and old-uidvalidity
	     (not (equal old-uidvalidity uidvalidity))
             (or (not start-article)
                 (> start-article 1))))
      (gnus-group-remove-parameter info 'uidvalidity)
      (gnus-group-remove-parameter info 'modseq))
     ;; We have the data needed to update.
     (t
      (let* ((group (gnus-info-group info))
	     (completep (and start-article
			     (= start-article 1)))
	     (active (or (gnus-active group)
			 (cdr (assq 'active (gnus-info-params info))))))
	(when uidnext
	  (setq high (1- uidnext)))
	;; First set the active ranges based on high/low.
	(if (or completep
		(not (gnus-active group)))
	    (gnus-set-active group
			     (cond
			      (active
			       (cons (min (or low (car active))
					  (car active))
				     (max (or high (cdr active))
					  (cdr active))))
			      ((and low high)
			       (cons low high))
			      (uidnext
			       ;; No articles in this group.
			       (cons uidnext (1- uidnext)))
			      (start-article
			       (cons start-article (1- start-article)))
			      (t
			       ;; No articles and no uidnext.
			       nil)))
	  (gnus-set-active group
			   (cons (car active)
				 (or high (1- uidnext)))))
	;; See whether this is a read-only group.
	(unless (eq permanent-flags 'not-scanned)
	  (gnus-group-set-parameter
	   info 'permanent-flags
	   (and (or (memq '%* permanent-flags)
		    (memq '%Seen permanent-flags))
		permanent-flags)))
	;; Update marks and read articles if this isn't a
	;; read-only IMAP group.
	(when (setq permanent-flags
		    (cdr (assq 'permanent-flags (gnus-info-params info))))
	  (if (and highestmodseq
		   (not start-article))
	      ;; We've gotten the data by QRESYNCing.
	      (nnimap-update-qresync-info
	       info existing (nnimap-imap-ranges-to-gnus-ranges vanished) flags)
	    ;; Do normal non-QRESYNC flag updates.
	    ;; Update the list of read articles.
	    (unless start-article
	      (setq start-article 1))
	    (let* ((unread
		    (gnus-compress-sequence
		     (gnus-set-difference
		      (gnus-set-difference
		       existing
		       (gnus-sorted-union
			(cdr (assoc '%Seen flags))
			(cdr (assoc '%Deleted flags))))
		      (cdr (assoc '%Flagged flags)))))
		   (read (range-difference
			  (cons start-article high) unread)))
	      (when (> start-article 1)
		(setq read
		      (gnus-range-nconcat
		       (if (> start-article 1)
			   (range-intersection
			    (cons 1 (1- start-article))
			    (gnus-info-read info))
			 (gnus-info-read info))
		       read)))
	      (when (or (not (listp permanent-flags))
			(memq '%Seen permanent-flags))
		(setf (gnus-info-read info) read))
	      ;; Update the marks.
	      (setq marks (gnus-info-marks info))
	      (dolist (type (cdr nnimap-mark-alist))
		(when (or (not (listp permanent-flags))
			  (memq (car (assoc (caddr type) flags))
				permanent-flags)
			  (memq '%* permanent-flags))
		  (let ((old-marks (assoc (car type) marks))
			(new-marks
			 (gnus-compress-sequence
			  (cdr (or (assoc (caddr type) flags) ; %Flagged
				   (assoc (intern (cadr type) obarray) flags)
				   (assoc (cadr type) flags)))))) ; "\Flagged"
		    (setq marks (delq old-marks marks))
		    (pop old-marks)
		    (when (and old-marks
			       (> start-article 1))
		      (setq old-marks (range-difference
				       old-marks
				       (cons start-article high)))
		      (setq new-marks (gnus-range-nconcat old-marks new-marks)))
		    (when new-marks
		      (push (cons (car type) new-marks) marks)))))
	      ;; Keep track of non-existing articles.
	      (let* ((old-unexists (assq 'unexist marks))
		     (active (gnus-active group))
		     (unexists
		      (if completep
			  (range-difference
			   active
			   (gnus-compress-sequence existing))
			(range-add-list
			 (cdr old-unexists)
			 (range-list-difference
			  existing (gnus-active group))))))
		(when (> (car active) 1)
		  (setq unexists (range-concat
				  (cons 1 (1- (car active)))
				  unexists)))
		(if old-unexists
		    (setcdr old-unexists unexists)
		  (push (cons 'unexist unexists) marks)))
	      (gnus-info-set-marks info marks t))))
	;; Tell Gnus whether there are any \Recent messages in any of
	;; the groups.
	(let ((recent (cdr (assoc '%Recent flags))))
	  (when (and active
		     recent
		     (> (car (last recent)) (cdr active)))
	    (push (list (cons group 0)) nnmail-split-history)))
	;; Note the active level for the next run-through.
	(gnus-group-set-parameter info 'active (gnus-active group))
	(gnus-group-set-parameter info 'uidvalidity uidvalidity)
	(gnus-group-set-parameter info 'modseq highestmodseq)
	(nnimap-store-info info (gnus-active group)))))))