Subject: Re: bug#72949: Gnus sometimes reports new messages but not showing them on IMAP server

From: Dan Christensen <[email-masked]>
Date: Mon, 16 Sep 2024 12:42:38 +0000

On Sep 16, 2024, James Thomas <[email-masked]> wrote:

> Wait! I think we've miscommunicated: I'd meant the _other_ patch, the
> one in (gnus-summary-goto-article "<[email-masked]>"). I use
> that and it's working fine here.

I believe you are talking about the patch to nnimap-request-group that
swaps the car and the cdr:

 	(insert (format "211 %d %d %d %S\n"
 			(- (cdr active) (car active))
-			(car active)
 			(cdr active)
+			(car active)
 			group))

After that patch, the relevant part of nnimap-request-group would look
like:

	(setq active (or active '(0 . 1)))
	(erase-buffer)
	(insert (format "211 %d %d %d %S\n"
			(- (cdr active) (car active))
			(cdr active)
			(car active)
			group))

This code has two bugs that (mostly) cancel each other out.  First, when
the group is empty, it represents that with the active range (0 . 1).
But that active range represents a group with two articles, numbered 0
and 1.  If you look throughout Gnus, the empty group is always
represented by the range (1 . 0).

Second, this code has the car and the cdr in the wrong order.
Everywhere else in Gnus that creates a 211 line from an active
range puts the car before the cdr.  In the case of an empty group,
these two bugs cancel.  But if active already had a non-nil value,
then the car and the cdr would be wrong.  And even if the active
range is always nil at this point, I don't approve of code that
has two bugs that cancel.

After my proposed patch (attached again), the code looks like

	(setq active (or active '(1 . 0)))
	(erase-buffer)
	(insert (format "211 %d %d %d %S\n"
			(max (1+ (- (cdr active) (car active))) 0)
			(car active)
			(cdr active)
			group))

Now the active range is correctly set to (1 . 0) for an empty group.
This alone doesn't work, as the expression (- (cdr active) (car active))
in the current code would then give a negative value for the number of
articles, which breaks at least one other place in Gnus.  So we use
the calculation that nnml-request-group uses to get the correct number
of articles in the range (by adding 1), and also force negative values
to 0, just in case active contains some bogus data.

I think this is the correct way to proceed, in line with how all
the other parts of Gnus create the 211 line.

Dan

diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 17a55f98..cdd9f01f 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -918,10 +918,10 @@ nnimap-request-group
 	    (nnimap-finish-retrieve-group-infos server info sequences
 						t)
 	    (setq active (nth 2 (assoc group nnimap-current-infos)))))
-	(setq active (or active '(0 . 1)))
+	(setq active (or active '(1 . 0)))
 	(erase-buffer)
 	(insert (format "211 %d %d %d %S\n"
-			(- (cdr active) (car active))
+			(max (1+ (- (cdr active) (car active))) 0)
 			(car active)
 			(cdr active)
 			group))