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: Pip Cet <pipcet <at> protonmail.com> To: Lynn Winebarger <owinebar <at> gmail.com> Cc: 78737 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>, Daniel Colascione <dancol <at> dancol.org>, Stefan Monnier <monnier <at> iro.umontreal.ca> Subject: bug#78737: sit-for behavior changes when byte-compiled Date: Sat, 14 Jun 2025 06:28:06 +0000
"Lynn Winebarger" <owinebar <at> gmail.com> writes: > On Fri, Jun 13, 2025 at 10:02 AM Daniel Colascione <dancol <at> dancol.org> wrote: >> >> >> >> On June 13, 2025 6:42:58 AM PDT, Daniel Colascione <dancol <at> dancol.org> wrote: >> > >> > >> >On June 13, 2025 5:23:34 AM PDT, Lynn Winebarger <owinebar <at> gmail.com> wrote: >> >>On Fri, Jun 13, 2025, 2:26 AM Eli Zaretskii <eliz <at> gnu.org> wrote: >> >> >> >>> > 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? >> >>> >> >> >> >>What about keeping a (possibly buffer-local?) lisp variable holding a list >> >>of keystrokes mapped to thunks that are treated as generating lisp machine >> >>"interrupts"? The key strokes would be processed by C machinery and never >> >>seen directly by lisp code and not be considered "events". >> >>Then C-g could be bound to a thunk signalling quit, and the effect of >> >>"inhibit-quit" achieved by removing C-g from the list in a given dynamic >> >>scope. Then user code could make other key-strokes "special" without >> >>resorting to read-event. For example, this read-event call in term.el: >> >>(message "Hit space to flush") >> >> (let ((ch (read-event))) >> >> (if (eq ch ?\s) >> >> (set-window-configuration conf) >> >> (push ch unread-command-events))) >> >> >> >>Could be replaced by something like >> >>(with-interrupts ((?\s (signal term-flush))) >> >> (condition-case nil >> >> (while t (sit-for 100)) >> >> (term-flush (set-window-configuration conf)))) >> >> >> >>Then some of these use-case concerns could be mooted altogether. >> > >> >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. 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. 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. But, again, such decisions ultimately require actually writing code, and I haven't, so far. > It would also mean a C-g (or other designated interrupt) could be > processed earlier than preceding keystrokes, but that seems like what > Pip would want? That's the current behavior. I'd like to keep it. Quit has some immediate effects, including sometimes clearing unread-command-events, discarding queued input. It also sets the quit flag before other input is processed. It then causes an actual quit, which is an error, which causes Fdiscard_input to be called. >> Oh yeah, one thing I forgot to mention: for the *asynchronous* case, >> the C code is pretty deeply coupled to quit_char, and IIRC, even >> hard codes 7, C-g, in some places instead of quit_char. In your >> proposal, we'd references to quit_char and literal 7 to calls to a >> new bool is_quit_char(int c) function -- and this function would >> return true for any raw keys bound in special-event-map. In this >> way, you'd be able to define as many asynchronous-input characters >> as you wanted. > I guess I would consider removing that kind of hard-coded logic a > plus? I think whether to make quit_char configurable (in GUI sessions) or keep the code which makes it configurable (in terminal sessions only) is a very minor detail. This comment in bindings.el: ;; The following wouldn't work to interrupt running code since C-g is ;; treated specially in the event loop. ;; (define-key global-map [stop] 'keyboard-quit) ; Sun suggests someone once wanted to add an additional quit_char and gave up. Pip
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.