emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: while-no-input


From: Richard Stallman
Subject: Re: while-no-input
Date: Tue, 30 Nov 2004 02:03:08 -0500

    > The only thing programs do to control quitting is to bind inhibit-quit
    > on and off.  That is not relevant to handling with-no-input, so I think

    Could you substantiate that claim?
    AFAIK inhibit-quit is used to get more-or-less-atomic behavior in places
    where it matters.  while-no-input should very clearly obey inhibit-quit

I am not sure about that point, but the issue at hand is how to do the
nonlocal exit.  If while-no-input's implementation looks at
inhibit-quit, that is orthogonal to how do to the nonlocal exit.  So
let me make my statement more precise:

The only thing programs do to control quitting is to bind inhibit-quit
on and off.  Since inhibit-quit has no effect on what either Fsignal
or Fthrow does when it is called, using Fthrow instead of Fsignal is
entirely orthogonal to anything user programs do to control quitting.

    Here is another way to say the ame thing: of all the non-local
    exits we have right now, `quit' is the only one that's
    asynchronous.

The setting of Vquit_flag is asynchronous, but I don't see that
that relates to the issue.  Quitting itself can be done asynchronously
in a few primitives, but usually it occurs synchronously in a place
that checks for it and does QUIT.

The operational difference between signal and throw is that the former
is caught by `condition-case' while the latter is caught by `catch'.
So the way to decide the issue is based on whether `condition-case'
ought to catch this.  If the definition of with-no-input is that
it alone catches this, then it has to use `catch'.

So here's my simpler proposal for how to implement this.


(defmacro while-no-input (&rest body)
  "Execute BODY only as long as there's no pending input.
If input arrives, that ends the execution of BODY."
  (declare (debug t) (indent 0))
  (let ((catch-sym (make-symbol "input")))
    `(with-local-quit
       (catch ',catch-sym
         (let ((throw-on-input ',catch-sym))
           (when (sit-for 0 0 t)
             ,@body))))))

#define QUIT                                            \
  do {                                                  \
    if (!NILP (Vquit_flag) && NILP (Vinhibit_quit))     \
      {                                                 \
        Lisp_Object flag = Vquit_flag;                  \
        Vquit_flag = Qnil;                              \
        if (EQ (Vthrow_on_input, flag))                 \
          Fthrow (Vthrow_on_input, Qnil);               \
        Fsignal (Qquit, Qnil);                          \
      }                                                 \
    else if (interrupt_input_pending)                   \
      handle_async_input ();                            \
  } while (0)
    



Index: keyboard.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/keyboard.c,v
retrieving revision 1.708
diff -u -u -b -r1.708 keyboard.c
--- keyboard.c  27 Sep 2002 17:03:46 -0000      1.708
+++ keyboard.c  1 Oct 2002 21:15:14 -0000
@@ -3374,6 +3402,9 @@
 }
 #endif
 
+
+Lisp_Object Vthrow_on_input;
+
 /* Store an event obtained at interrupt level into kbd_buffer, fifo */
 
 void
@@ -3501,6 +3538,14 @@
       ASET (kbd_buffer_gcpro, idx + 1, event->arg);
       ++kbd_store_ptr;
     }
+  
+  /* If we're in a section that requested to be interrupted as soon
+     as input comes, then set quit-flag to cause an interrupt.  */
+  if (!NILP (Vthrow_on_input)
+      && event->kind != FOCUS_IN_EVENT
+      && event->kind != HELP_EVENT
+      && event->kind != DEICONIFY_EVENT)
+    Vquit_flag = Vthrow_on_input;
 }
 
 
@@ -11038,6 +11029,12 @@
               doc: /* *How long to display an echo-area message when the 
minibuffer is active.
 If the value is not a number, such messages don't time out.  */);
   Vminibuffer_message_timeout = make_number (2);
+
+  DEFVAR_LISP ("throw-on-input", &Vthrow_on_input,
+              doc: /* If non-nil, any keyboard input throws to this symbol.
+The value of that variable is passed to `quit-flag' and later causes a
+peculiar kind of quitting.  */);
+  Vthrow_on_input = Qnil;
 }
 
 void




reply via email to

[Prev in Thread] Current Thread [Next in Thread]