Package: emacs;
Reported by: Daniel Colascione <dancol <at> dancol.org>
Date: Mon, 9 Jun 2025 20:50:02 UTC
Severity: normal
View this message in rfc822 format
From: Eli Zaretskii <eliz <at> gnu.org> To: Daniel Colascione <dancol <at> dancol.org> Cc: 78737 <at> debbugs.gnu.org, pipcet <at> protonmail.com, monnier <at> iro.umontreal.ca Subject: bug#78737: sit-for behavior changes when byte-compiled Date: Fri, 13 Jun 2025 09:25:36 +0300
> From: Daniel Colascione <dancol <at> dancol.org> > Cc: Eli Zaretskii <eliz <at> gnu.org>, monnier <at> iro.umontreal.ca, > 78737 <at> debbugs.gnu.org > Date: Thu, 12 Jun 2025 11:48:50 -0700 > > Pip Cet <pipcet <at> protonmail.com> writes: > > > I'd like read-event, when called while inhibit-quit is t, to report > > quits by setting quit-flag in addition to returning quit_char: it'll > > simplify the C code, and it would make > > > > (while t > > (let ((inhibit-quit t)) > > (read-event))) > > I strongly disagree. read-event should read an event. > Setting quit-flag by side effect when it happens to read one key and not > others makes the interface less regular and understandable. We should start by agreeing that the capability of interrupting a running Lisp program is a real need. Are we in agreement about that? If not, let's first hear the arguments why not. If we _are_ in agreement about that, we should discuss how this should be possible if read-event (and perhaps others?) return C-g instead of raising quit-flag. The alternatives mentioned until now are: . restore the old behavior, whereby C-g interrupts read-event . have a variable that, if set, will restore the old behavior in read-event and other affected primitives, to be interruptible by a single C-g . make two C-g presses "in quick succession" set quit-flag, IOW "C-g C-g" will have the same effect as C-g previously Are there other alternatives? > read-key-sequence is the high-level function. read-event is the > low-level function. It makes zero sense for the high-level function to > report a key event as a low-level event and for the low-level function > to do special non-local flow control in response to that event. > > > quittable, as I naively expected it to be. > > The naive expectation is that this function do its job. I don't think there's disagreement on that level. So let's drop this kind of arguments, because they are not useful for this discussion. The problem we face is how to allow Lisp code to be quittable. A Lisp program that calls read-event is not different from a Lisp program calling any other function, so we still need such programs to be quittable somehow. Let's discuss how best to do it, okay? > > Several force-quits in the same session. Reset force_quit_count to 0 > > once it reaches 3. I've seen force_quit_count reach higher values than > > 3 (there was no regular quit in between force quit attempts). > > Get rid of force_quit_count entirely and just detect (by writing into a > ring buffer) whether we've received N quits in the last T milliseconds. > That'll work the same way regardless of how quits gets detected. We can > change N and T freely. This is the last alternative I described above. It is IMO less desirable, because it is not always easy to press C-g twice quickly, for whatever reasons. It is even less desirable to define "quick succession" in terms of time, because timings can differ a lot depending on the free computing resources and the CPU power in general, so determining the best default values will be very challenging, to say the least. > On your Emacs, you can set N to one and T to zero. If read-event still returns a keyboard input event when C-g is pressed, I don't see how N = 1 would work. Can you describe how it would work? > >> 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. > > > Absolutely. We could easily make it customizable whether read-event > > sets quit-flag after a quit: > > > > 1. never > > 2. only when !inhibit-quit > > 3. always > > We can customize thresholds for general behavior, but I don't think we > should not have preferences that alter the operation of fundamental > Emacs primitives. You couldn't add a preference that made if regard 0 > as well as nil as false, would you? Why not? If it helps debugging, we could definitely do that. We already have --enable-checking, which changes how some primitives work, in a very real sense. As long as the feature is for debugging Emacs, anything useful goes, IMO. > >>> 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? > >> > >> 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. > > > > And we'd need a way to detect when a quit is handled (however we define > > "handled") so we could reset force_quit_counter. Not a trivial change. > > You don't. You just upgrade any quit that happens under the N and T > threshold above. I'm skeptical that we will be able to count C-g presses so as to reliably differentiate between double or triple press and two or three separate C-g presses. Different machines and OSes, and different system loads, can make it nigh impossible to do reliably. And that's _bad_, because when I want something interrupted right away, I don't want or even cannot try again and again and again until it works.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.