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

From: Daniel Colascione <[email-masked]>
Date: Sat, 14 Jun 2025 07:11:14 -0400

On June 14, 2025 2:28:06 AM EDT, Pip Cet <[email-masked]> wrote:
>"Lynn Winebarger" <[email-masked]> writes:
>
>> On Fri, Jun 13, 2025 at 10:02 AM Daniel Colascione <[email-masked]> wrote:
>>>
>>>
>>>
>>> On June 13, 2025 6:42:58 AM PDT, Daniel Colascione <[email-masked]> wrote:
>>> >
>>> >
>>> >On June 13, 2025 5:23:34 AM PDT, Lynn Winebarger <[email-masked]> wrote:
>>> >>On Fri, Jun 13, 2025, 2:26 AM Eli Zaretskii <[email-masked]> wrote:
>>> >>
>>> >>> > From: Daniel Colascione <[email-masked]>
>>> >>> > Cc: Eli Zaretskii <[email-masked]>,  [email-masked],
>>> >>> >   [email-masked]
>>> >>> > Date: Thu, 12 Jun 2025 11:48:50 -0700
>>> >>> >
>>> >>> > Pip Cet <[email-masked]> 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.

Not out of the box, true. In principle, though, it would be possible to scan special-event-map for single-key bindings and treat them all like we do quit_char for purposes of Lisp interruption, input discarding, and so on.

For example, while I'm debugging something, it'd actually be nice to have a single key to instantly invoke the debugger without having to deal with the inconvenience of debug-on-quit breaking into the debugger in a lot of places I would rather it not.

Likewise, it'd be convenient to have the ability to bind a key at a low level to something that would instantly launch and attach GDB without having to deal with the friction of creating a terminal, finding the Emacs PID, starting the debugger, and attaching by hand.

Not the most important thing to do right now, but there do seem to be actual use cases for binding behaviors to keys in the manner we do for quits.