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

From: Pip Cet <[email-masked]>
Date: Tue, 10 Jun 2025 17:40:39 +0000

"Stefan Monnier" <[email-masked]> writes:

>> BTW: the problem isn't just with transient. It also manifests with
>> read-extended-command! It's a nasty race that, AFAICT, has been with us
>> since the 90s. I think defining read_char to translate quits to quit_char
>> solves the problem.
>
> I like your way of thinking.  I'm not completely sure it will solve
> world hunger, and it may come with regressions, but it's worth a try.

I must be missing something: read_char translates quits to quit_char if
called with inhibit-quit bound to t, and never returns with quit-flag
set to t in that case.  I don't think it should do that, it doesn't
match the quit-flag documentation, but it is what happens right now.  Do
we really need a new function which is precisely equivalent to

(let ((inhibit-quit t)) (read-event ...)) ?

As for throw-on-input, I don't know what Daniel is proposing to do to
handle it.  Is every caller of read-event supposed to check
throw-on-input and simulate it?  How is that better than looking at
quit-flag, or simply keeping inhibit-quit bound for the critical
section?

As for peeking at events, the easiest way seems to me to be to let-bind
unread-command-events to nil around a call to read-event.  That'll make
it ignore them, read the next event, which you can then append to
unread-command-events or not depending on whether you want the command
loop to handle it.

> Given the pervasive impact, it might be best to have a global config var
> to enable/disable it (with some scary internal name) until we're
> confident that it's an improvement.

I agree it would make sense to separate inhibit-quit meaning "inhibit
acting on the quit flag" and inhibit-quit meaning "inhibit setting the
quit flag", but that seems a minor change.

Pip