Subject: Re: bug#78916: 31.0.50; C-g fails to exit loop

From: Eli Zaretskii <[email-masked]>
Date: Tue, 01 Jul 2025 14:46:27 +0300

> From: Stefan Monnier <[email-masked]>
> Cc: [email-masked],  [email-masked]
> Date: Mon, 30 Jun 2025 16:15:17 -0400
> 
> Eli Zaretskii [2025-06-30 22:00:02] wrote:
> 
> >> From: Stefan Monnier <[email-masked]>
> >> Cc: Mike Kupfer <[email-masked]>,  [email-masked]
> >> Date: Mon, 30 Jun 2025 12:01:02 -0400
> >> 
> >> >> > - Both keys behave like the "old C-g".
> >> >> > ?
> >> >> I'm fine with that.
> >> > Same, but does it mean 'C-g' will do the same as 'q'?  If not, what is
> >> > the difference between them?
> >> 
> >> Hmm... so `q` is bound to `exit` which consumes the key and exits the
> >> Q&R loop.  In contrast `C-g` and `C-]` were bound to `quit` which is
> >> not handled exlicitly by the Q&R loop, instead it just pushes the event
> >> back on the `unread-commend-events` before exiting the loop, so in
> >> Mike's test case, `q` exits the inner Q&R and passes to the next,
> >> whereas `C-]` aborts all the subsequent Q&R calls after which it runs
> >> the global binding of `C-[`.
> >
> > I think I understand what you are saying about the difference between
> > 'q' and 'C-g', but I don't see any nested query-replace in Mike's test
> > case, or what did I miss?  Or maybe I misunderstood what you mean by
> > "the next"?
> 
> His Q&R call is inside a loop:
> 
>          (while (re-search-forward "bug#[[:digit:]]+:" nil t)
>            (search-backward "(\"bug")
>            (let (end (start (point)))
>              (forward-sexp)
>              (setq end (point))
>              (query-replace-regexp "\\(\"bug#[[:digit:]]+:\\).*\"" "\\1\""
>              		    nil start end))))
> 
> so when we exit one we enter the next (as long as there's another match
> for the main regexp, that is).

OK, but then the issue here is not about query-replace-regexp at all,
isn't it?  It's about whether C-g is "re-read" after exiting
query-replace-regexp, and when it is re-read, does it quit.  Or am I
missing something?

> > In any case, this difference between 'q' and 'C-g' is not explained in
> > the user manual.  The manual uses different wording to describe them,
> > but my interpretation of the text is that they have the same effect.
> 
> So in effect we've had 3 "identical" yet subtly different behaviors for
> years:
> 
> - The behavior of `q`: exit the Q&R and continue with whatever may follow.
> - The behavior of `C-]`: exit the Q&R and also continue with whatever
>   may follow, but without consuming the `C-]` so next time we read a key
>   we'll get this `C-]`.
> - The old behavior of `C-g` (which we definitely want to recover): abort
>   the current command.

If C-g is not consumed, it will produce the expected effect, right?
If so, the problem seems to be that this is what's expected here, and
it happened in the past because C-g would quite right away, so there
was no need to re-read it.  Right?