"Lynn Winebarger" <owinebar@gmail.com> writes:
> On Fri, Jun 13, 2025 at 10:02 AM Daniel Colascione <dancol@dancol.org> wrote:
>>
>>
>>
>> On June 13, 2025 6:42:58 AM PDT, Daniel Colascione <dancol@dancol.org> wrote:
>> >
>> >We already have something like that. :-) read-event already runs
>> > the events it reads through special-event-map, right? We don't
>> > even need to create a separate thunk list concept: we could just
>> > bind C-g in special event map and do what we want, right?
> Would that provide the behavior Pip is looking for?
It would not, because quits are currently processed out-of-order, and
this important feature should remain in place for "serious" quits. See
below.
>> >The only special thing about C-g is how we treat it when Lisp is
>> > running. When it's instead reading an event, it can and be a
>> > boring event processed the same way every other event is.
> It seems to me what Pip is looking for is analogous to a "Quit" button
> hardwired to a pin on a CPU, which is not something that can be
> reliably implemented in the C primitives as they are now.
You're suggesting I'm looking for something that cannot be implemented.
I'm not.
That was not my intention. I don't think that hard-wired behavior can be reliably implemented one read_char has started processing an input event off its queue. There's just too many ways a keystroke can get consumed or discarded that may not even be in the C primitives, as far as I can tell. At least, that's what it looks like from a cursory reading of read_char.
It seems to me the most reliable way to guarantee C-g or any other designated special input is treated specially is to make sure they don't enter the queue processed by read_char at all. And the most reliable way to do that is probably to make the signal handler indicating keystrokes are available, split the special keystrokes off into their own queue right from the start. How much actual processing might be done from the handler's activation frame is a separate matter. For example, the signal handler could increment a quit count if it isn't already, then do something more aggressive if the count exceeds some threshold, like throwing directly from the signal handler rather than waiting for the C code to reach some point safe for throwing.
I described specific situations in which I think quit should be expanded
to work better than it does now. No one's expecting that quit works in
absolutely every situation, as far as I know. That's what gdb is for.
Actually, I'd love C-g to reliably interrupt Emacs when it appears locked up and I have no idea why. It's probably annoying to other users who don't have a copy of Emacs built for debugging to not be able to kick Emacs out of an infinite loop (or worse) as well.
If you're referring to the "C-g C-g" thing, I did not describe how I'd
implement it in detail, because there are many choices to be made; but
the main idea would be that we should not immediately clear inhibit-quit
for that combination, because that's a dangerous and destructive thing
to do. If we decide to do so (after a delay, for example), we need to
print a clear warning to the user that their Emacs session needs
restarting.
So C-g C-g might do less than GUI C-g C-g C-g does currently.
There are actions even more dangerous than clearing inhibit-quit. I
don't know whether we want a level-3 quit which does even more than the
current GUI C-g C-g C-g code.
I don't really understand the necessity or use of inhibit-quit, as opposed to, say, pushing a new quit handler or blocking input altogether, if the consistency of the lisp machine state is a concern (e.g. to prevent throwing from a signal handler).
Lynn