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

From: Stefan Monnier <[email-masked]>
Date: Sat, 28 Jun 2025 15:14:34 -0400

Hi Mike,

> 2. Evaluate the following defun:
>
> (defun do-test ()
>   (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))))
>
> 3. Visit the test data file.  With point at the start of the buffer, run
> the do-test function, and press space a couple times.  Now press C-g.
>
> Expected behavior:
>
>   The do-test function stops executing, and point is left at the same
>   position where you pressed C-g.  (This is the behavior I see with
>   Emacs 30 and with a build derived from Emacs master 648453c04d9.)
>
> Observed behavior:
>
>   point progresses through the remaining sexps, without giving you any
>   query-replace prompt.  When do-test has finished, point is now after
>   '"bug#78900:"'.

[ Thanks for your report.  I think this is a great data-point for the
  recent discussion around making `read-event` consistently return `C-g`
  (instead of signaling `quit`).  ]

In `query-replace-map` we have:

    (define-key map "\C-g" 'quit)
    (define-key map "\C-]" 'quit)

In Emacs<31 `C-g` gave what you describe as "Expected behavior", and
`C-]` gave what you describe as "Observed behavior".

In `master`, they now both behave in the same way.  I think the fact
that the behave the same way is good/right since they have the same
binding in the keymap.

So what do we want:

- Both keys behave like the "old C-g".
- Both keys behave like the "old C-]" (i.e. what we have now).
- Reintroduce the difference of behavior between `C-g` and `C-]`,
  presumably by giving them different bindings in `query-replace-map.

        Stefan