Subject: bug#78737: sit-for behavior changes when byte-compiled

From: Daniel Colascione <[email-masked]>
Date: Thu, 12 Jun 2025 09:52:22 -0700

On June 12, 2025 9:32:26 AM PDT, Eli Zaretskii <[email-masked]> wrote:
>> Date: Thu, 12 Jun 2025 13:58:51 +0000
>> From: Pip Cet <[email-masked]>
>> Cc: Eli Zaretskii <[email-masked]>, [email-masked], [email-masked]
>> 
>> I'd say breaking (read-event) called in a loop is bad enough, because
>> how else are you supposed to start developing code which uses it?
>
>Maybe this regression should be fixed, then.

It's not a regression. It's a bug fix. Not every behavior change is a problem. Who starts coding something by calling it in a loop? That's like learning to drive by crashing into a wall.

And besides, like I keep saying, read-key-sequence works the same way read-event does and over lots of decades nobody to my knowledge has called it unprogrammable.

You have to think about these things, not just reflexively conclude that it's bad because it's different.

>> Since we've progressed to testing the branch, with the implication being
>> that we'll merge it soon, it may be too late to make alternative
>> suggestions.
>
>We will merge only after we agree that (a) it does TRT, and (b) that
>it was tested sufficiently well and all the problems it might cause
>have been dealt with.
>
>So it isn't too late to argue that the branch does something
>incorrectly or sub-optimally.
>
>> I think this discussion is concerned too much with what existing code
>> will break if we change quit not to quit, not enough with how much more
>> difficult it will be to develop code if we do, and not at all, so far,
>> with what the advantages of handling quit in Lisp (if Lisp decides to
>> handle it at all) are.
>> 
>> C-g isn't an input event in the same way that kicking someone in the
>> shin is not a dance move.  I want it to kick Emacs in the shin, and
>> break out of bad Lisp code, in *more* situations than it does now.
>
>Please describe the situations where you'd like it to throw to top
>level and it doesn't now.  Also, can this behavior be optional, like
>debug-on-error and friends are?  Not everyone debugs Lisp code all the
>time, so we definitely can have an "easy-break-out" feature that is by
>default off.
>
>> Maybe a compromise would be to continue the arms race and downgrade C-g
>> to normal input, C-g C-g C-g to a quit, and require even more C-g's for
>> a force-quit?

Yes, that's what I have in mind, and it'll help in other situations in which we eat C-g today. Don't think of it as upgrading a quit, but rather hinting to Emacs that it should interpret C-g as quit in situations it would otherwise interpret it as an event. Not every C-g is a quit.

The branch creates a simple mental model of how this works:

1. By default, C-g is an input event like everything else. You can read it, read a key sequence involving it, and bind it to keymaps like any other key.

2. As a special feature, Emacs interprets C-g while Lisp is running (not blocked on input) to mean that it should raise a special signal, called quit, and take you back to the command loop ASAP.

3. Lisp code can disable #2 in a section of code by binding inhibit-quit around anything that's important to run without interruption.

4. If you hit C-g enough times in a short enough time, we treat C-g as a quit even in contexts where we're trying to read input. We display a message when doing so. For example, at this stage, we can break out of (while t (read-char)).

5. If you continue to hit C-g, we conclude Emacs is hooked and disable inhibit-quit so you can break out of sections of code marked ordinarily unbreakable. Doing so may break your Emacs, so we'll display a message saying this has happened.

#4 and #5 aren't implemented on the branch, but will be. We do have a legacy force quit feature, but it skips #4 and goes straight to #5, and it never worked for me in GUI Emacs anyway.

>That's also possible, though less desirable: counting C-g presses when
>you are desperate is not easy and we cannot rely on users to do that
>reliably.