unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* while-no-input
@ 2002-10-01 21:19 Stefan Monnier
  2002-10-02 19:24 ` while-no-input Richard Stallman
  0 siblings, 1 reply; 32+ messages in thread
From: Stefan Monnier @ 2002-10-01 21:19 UTC (permalink / raw)



Sometimes I'd like to be able to run something "while there's nothing
else to do".  For example, right now icomplete does not work when
completing file names because getting the list of completions can take
an exceedingly long time.  But if it could say "try to build the list
but abort as soon as the user hits a key", then we could use it
there just fine.

So I have a little patch that does just that.  What it does:

1 - add a quit-on-input variable that causes a quit signal to be sent
    as soon as some user input comes in (and the variable is non-nil).

2 - change QUIT to pass the value of `quit-flag' as part of the quit
    signal so we can tell the difference between a real `quit' and
    a `quit-on-input'.

3 - add a `while-no-input' macro that uses the above facilities to run
    its body and exit as soon as user-input is detected.


	Stefan


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 Vquit_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 (Vquit_on_input)
+      && event->kind != FOCUS_IN_EVENT
+      && event->kind != HELP_EVENT
+      && event->kind != DEICONIFY_EVENT)
+    Vquit_flag = Vquit_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 ("quit-on-input", &Vquit_on_input,
+	       doc: /* If non-nil, any input will cause a `quit' signal to be thrown.
+The value of that variable is passed to `quit-flag' and is later carried
+by the `quit' signal.  */);
+  Vquit_on_input = Qnil;
 }
 
 void
Index: lisp.h
===================================================================
RCS file: /cvsroot/emacs/emacs/src/lisp.h,v
retrieving revision 1.440
diff -u -r1.440 lisp.h
--- lisp.h	11 Sep 2002 01:59:33 -0000	1.440
+++ lisp.h	1 Oct 2002 21:17:54 -0000
@@ -1759,8 +1760,9 @@
   do {							\
     if (!NILP (Vquit_flag) && NILP (Vinhibit_quit))	\
       {							\
+	Lisp_Object flag = Vquit_flag;			\
 	Vquit_flag = Qnil;				\
-	Fsignal (Qquit, Qnil);				\
+	Fsignal (Qquit, flag);				\
       }							\
   } while (0)
 
Index: subr.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/subr.el,v
retrieving revision 1.326
diff -u -r1.326 subr.el
--- subr.el	29 Sep 2002 18:37:43 -0000	1.326
+++ subr.el	1 Oct 2002 21:18:28 -0000
@@ -1606,11 +1622,25 @@
 
 (defmacro with-local-quit (&rest body)
   "Execute BODY with `inhibit-quit' temporarily bound to nil."
+  (declare (debug t) (indent 0))
   `(condition-case nil
        (let ((inhibit-quit nil))
 	 ,@body)
      (quit (setq quit-flag t))))
 
+(defmacro while-no-input (&rest body)
+  "Execute BODY as long as there's no pending input."
+  (declare (debug t) (indent 0))
+  (let ((quit-sym (make-symbol "input")))
+    `(with-local-quit
+       (condition-case err
+	   (let ((quit-on-input ',quit-sym))
+	     (when (sit-for 0 0 t)
+	       ,@body))
+	 ;; Check it is indeed a quit-on-input.  If not, rethrow the signal.
+	 (quit (unless (eq (cdr err) ',quit-sym)
+		 (signal (car err) (cdr err))))))))
+
 (defmacro combine-after-change-calls (&rest body)
   "Execute BODY, but don't call the after-change functions till the end.
 If BODY makes changes in the buffer, they are recorded

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-01 21:19 while-no-input Stefan Monnier
@ 2002-10-02 19:24 ` Richard Stallman
  2002-10-02 21:43   ` while-no-input Stefan Monnier
  0 siblings, 1 reply; 32+ messages in thread
From: Richard Stallman @ 2002-10-02 19:24 UTC (permalink / raw)
  Cc: emacs-devel

It is a general principle that to avoid using abnormal
condition handling for programmed control flow.
I think it is very unclean to treat ordinary input
like a quit and then distinguish them later.
So I don't think we should add this mechanism.

It is easy enough to do the job using input-pending-p.
You can use

  (catch 'input
    (...
      (if (input-pending-p) (throw 'input nil))
      ...))

if you want to avoid testing input-pending-p at various
levels in the code.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-02 19:24 ` while-no-input Richard Stallman
@ 2002-10-02 21:43   ` Stefan Monnier
  2002-10-03 13:28     ` while-no-input Richard Stallman
  0 siblings, 1 reply; 32+ messages in thread
From: Stefan Monnier @ 2002-10-02 21:43 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, emacs-devel

> It is a general principle that to avoid using abnormal
> condition handling for programmed control flow.
> I think it is very unclean to treat ordinary input
> like a quit and then distinguish them later.
> So I don't think we should add this mechanism.
> 
> It is easy enough to do the job using input-pending-p.
> You can use
> 
>   (catch 'input
>     (...
>       (if (input-pending-p) (throw 'input nil))
>       ...))
> 
> if you want to avoid testing input-pending-p at various
> levels in the code.

That is not very useful if inside this body you use library
functions that take a long time to complete, such as file-operations
that dispatch to ange-ftp: you'd have to sprinkle (if (input-pending-p)
(throw 'input nil)) all over the ange-ftp code, just to help some
unrelated package like icomplete.


	Stefan

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-02 21:43   ` while-no-input Stefan Monnier
@ 2002-10-03 13:28     ` Richard Stallman
  2002-10-03 15:53       ` while-no-input Stefan Monnier
  2002-10-05 22:43       ` while-no-input Kim F. Storm
  0 siblings, 2 replies; 32+ messages in thread
From: Richard Stallman @ 2002-10-03 13:28 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, emacs-devel

    That is not very useful if inside this body you use library
    functions that take a long time to complete, such as file-operations
    that dispatch to ange-ftp:

It doesn't seem like a terribly important case to worry about.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-03 13:28     ` while-no-input Richard Stallman
@ 2002-10-03 15:53       ` Stefan Monnier
  2002-10-03 22:44         ` while-no-input Kim F. Storm
  2002-10-04 15:46         ` while-no-input Richard Stallman
  2002-10-05 22:43       ` while-no-input Kim F. Storm
  1 sibling, 2 replies; 32+ messages in thread
From: Stefan Monnier @ 2002-10-03 15:53 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, emacs-devel

>     That is not very useful if inside this body you use library
>     functions that take a long time to complete, such as file-operations
>     that dispatch to ange-ftp:
> 
> It doesn't seem like a terribly important case to worry about.

But that's the case that I'm bumping up against.
And the solution is pretty simple and localized as I have shown.


	Stefan

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-03 22:44         ` while-no-input Kim F. Storm
@ 2002-10-03 22:33           ` Stefan Monnier
  0 siblings, 0 replies; 32+ messages in thread
From: Stefan Monnier @ 2002-10-03 22:33 UTC (permalink / raw)
  Cc: Stefan Monnier, Richard Stallman, emacs-devel

> "Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:
> 
> > >     That is not very useful if inside this body you use library
> > >     functions that take a long time to complete, such as file-operations
> > >     that dispatch to ange-ftp:
> > > 
> > > It doesn't seem like a terribly important case to worry about.
> > 
> > But that's the case that I'm bumping up against.
> > And the solution is pretty simple and localized as I have shown.
> 
> I don't object to your while-no-input code (I can see it would be useful).
> 
> However, I would really like "find-file-all-completions" to be
> interruptable by keyboard input!
> 
> E.g. in ido-find-file, if I know I'm going to write x/y/z, there's
> really no reason for me to wait for emacs to build the completion
> lists for x and y.  But currently, I have to accept the delay.

That's the whole point of my patch (after all ido.el does pretty much the
same as icomplete from this particular viewpoint).


	Stefan

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-03 15:53       ` while-no-input Stefan Monnier
@ 2002-10-03 22:44         ` Kim F. Storm
  2002-10-03 22:33           ` while-no-input Stefan Monnier
  2002-10-04 15:46         ` while-no-input Richard Stallman
  1 sibling, 1 reply; 32+ messages in thread
From: Kim F. Storm @ 2002-10-03 22:44 UTC (permalink / raw)
  Cc: Richard Stallman, emacs-devel

"Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:

> >     That is not very useful if inside this body you use library
> >     functions that take a long time to complete, such as file-operations
> >     that dispatch to ange-ftp:
> > 
> > It doesn't seem like a terribly important case to worry about.
> 
> But that's the case that I'm bumping up against.
> And the solution is pretty simple and localized as I have shown.

I don't object to your while-no-input code (I can see it would be useful).

However, I would really like "find-file-all-completions" to be
interruptable by keyboard input!

E.g. in ido-find-file, if I know I'm going to write x/y/z, there's
really no reason for me to wait for emacs to build the completion
lists for x and y.  But currently, I have to accept the delay.

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-03 15:53       ` while-no-input Stefan Monnier
  2002-10-03 22:44         ` while-no-input Kim F. Storm
@ 2002-10-04 15:46         ` Richard Stallman
  2002-10-04 15:59           ` while-no-input Stefan Monnier
  1 sibling, 1 reply; 32+ messages in thread
From: Richard Stallman @ 2002-10-04 15:46 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, emacs-devel

    But that's the case that I'm bumping up against.
    And the solution is pretty simple and localized as I have shown.

The change is very ugly; too much to be justified by the intended
goal.

However, it would cleaner if instead of generating a quit signal it
did a throw to a specified tag.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-04 15:46         ` while-no-input Richard Stallman
@ 2002-10-04 15:59           ` Stefan Monnier
  2002-10-05 16:33             ` while-no-input Richard Stallman
  2002-10-24  0:06             ` while-no-input Kim F. Storm
  0 siblings, 2 replies; 32+ messages in thread
From: Stefan Monnier @ 2002-10-04 15:59 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, emacs-devel

>     But that's the case that I'm bumping up against.
>     And the solution is pretty simple and localized as I have shown.
> The change is very ugly; too much to be justified by the intended goal.

Could you explain what part you find ugly ?

> However, it would cleaner if instead of generating a quit signal it
> did a throw to a specified tag.

The reason I didn't do that is that it didn't seem necessary
and that I didn't want the QUIT macro to grow, but I could introduce
a new function `quit' that the QUIT macro could call and which would
either call `Fsignal (Qquit, Qnil)' ot `Fthrow (...)'.


	Stefan

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-04 15:59           ` while-no-input Stefan Monnier
@ 2002-10-05 16:33             ` Richard Stallman
  2002-10-24  0:06             ` while-no-input Kim F. Storm
  1 sibling, 0 replies; 32+ messages in thread
From: Richard Stallman @ 2002-10-05 16:33 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, emacs-devel

    The reason I didn't do that is that it didn't seem necessary
    and that I didn't want the QUIT macro to grow, but I could introduce
    a new function `quit' that the QUIT macro could call and which would
    either call `Fsignal (Qquit, Qnil)' ot `Fthrow (...)'.

That would be ok.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-03 13:28     ` while-no-input Richard Stallman
  2002-10-03 15:53       ` while-no-input Stefan Monnier
@ 2002-10-05 22:43       ` Kim F. Storm
  1 sibling, 0 replies; 32+ messages in thread
From: Kim F. Storm @ 2002-10-05 22:43 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, emacs-devel

Richard Stallman <rms@gnu.org> writes:

>     That is not very useful if inside this body you use library
>     functions that take a long time to complete, such as file-operations
>     that dispatch to ange-ftp:
> 
> It doesn't seem like a terribly important case to worry about.

For users of ido or icomplete as well as ange-ftp (or tramp?),
it is definitely a nuisance; I believe that the number of users
affected by this from time to time is fairly high.

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-04 15:59           ` while-no-input Stefan Monnier
  2002-10-05 16:33             ` while-no-input Richard Stallman
@ 2002-10-24  0:06             ` Kim F. Storm
  2002-10-24  7:20               ` while-no-input Stefan Monnier
  1 sibling, 1 reply; 32+ messages in thread
From: Kim F. Storm @ 2002-10-24  0:06 UTC (permalink / raw)
  Cc: Richard Stallman, emacs-devel

"Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:

> > However, it would cleaner if instead of generating a quit signal it
> > did a throw to a specified tag.
> 
> The reason I didn't do that is that it didn't seem necessary
> and that I didn't want the QUIT macro to grow, but I could introduce
> a new function `quit' that the QUIT macro could call and which would
> either call `Fsignal (Qquit, Qnil)' ot `Fthrow (...)'.

Richard Stallman <rms@gnu.org> writes:

> That would be ok.

Stefan,

What happened with this feature?

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-24  0:06             ` while-no-input Kim F. Storm
@ 2002-10-24  7:20               ` Stefan Monnier
  2002-10-24 10:24                 ` while-no-input Kim F. Storm
  0 siblings, 1 reply; 32+ messages in thread
From: Stefan Monnier @ 2002-10-24  7:20 UTC (permalink / raw)
  Cc: Stefan Monnier, Richard Stallman, emacs-devel

> "Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:
> 
> > > However, it would cleaner if instead of generating a quit signal it
> > > did a throw to a specified tag.
> > 
> > The reason I didn't do that is that it didn't seem necessary
> > and that I didn't want the QUIT macro to grow, but I could introduce
> > a new function `quit' that the QUIT macro could call and which would
> > either call `Fsignal (Qquit, Qnil)' ot `Fthrow (...)'.
> 
> Richard Stallman <rms@gnu.org> writes:
> 
> > That would be ok.
> 
> Stefan,
> 
> What happened with this feature?

Backburner.  Because I have other things to do for now and also because,
to tell you the truth, I'm not really psyched at the idea of using `throw'
instead of (signal 'quit <value>): after all this quit-on-input is really
a variant of `quit' and not something of a different nature.
Proof is that it should (and does) obey inhibit-quit.


	Stefan

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-24  7:20               ` while-no-input Stefan Monnier
@ 2002-10-24 10:24                 ` Kim F. Storm
  2002-10-25  5:35                   ` while-no-input Richard Stallman
  0 siblings, 1 reply; 32+ messages in thread
From: Kim F. Storm @ 2002-10-24 10:24 UTC (permalink / raw)
  Cc: Richard Stallman, emacs-devel

"Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:

> > "Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:
> > 
> > > > However, it would cleaner if instead of generating a quit signal it
> > > > did a throw to a specified tag.
> > > 
> > > The reason I didn't do that is that it didn't seem necessary
> > > and that I didn't want the QUIT macro to grow, but I could introduce
> > > a new function `quit' that the QUIT macro could call and which would
> > > either call `Fsignal (Qquit, Qnil)' ot `Fthrow (...)'.
> > 
> > Richard Stallman <rms@gnu.org> writes:
> > 
> > > That would be ok.
> > 
> > Stefan,
> > 
> > What happened with this feature?
> 
> Backburner.  Because I have other things to do for now and also because,
> to tell you the truth, I'm not really psyched at the idea of using `throw'
> instead of (signal 'quit <value>): after all this quit-on-input is really
> a variant of `quit' and not something of a different nature.
> Proof is that it should (and does) obey inhibit-quit.

IIRC, RMS said that using signal like that was very unclean and using throw
would be cleaner.

But I tend to agree with you that just using signal would be both
simpler and more correct (obeying inhibit-quit), and I really don't
see why using throw [making the implementation more trickly] can
be said to be (much) cleaner than your original approach!

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-24 10:24                 ` while-no-input Kim F. Storm
@ 2002-10-25  5:35                   ` Richard Stallman
  2002-10-25  9:19                     ` while-no-input Kim F. Storm
  2002-10-25 13:44                     ` while-no-input Stefan Monnier
  0 siblings, 2 replies; 32+ messages in thread
From: Richard Stallman @ 2002-10-25  5:35 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, emacs-devel

    IIRC, RMS said that using signal like that was very unclean and using throw
    would be cleaner.

That is the first thing I said.  Afterwards I agreed to a modified
version of the change which avoids the ugliness at the Lisp level.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-25  5:35                   ` while-no-input Richard Stallman
@ 2002-10-25  9:19                     ` Kim F. Storm
  2002-10-26 20:15                       ` while-no-input Richard Stallman
  2002-10-25 13:44                     ` while-no-input Stefan Monnier
  1 sibling, 1 reply; 32+ messages in thread
From: Kim F. Storm @ 2002-10-25  9:19 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, emacs-devel

Richard Stallman <rms@gnu.org> writes:

>     IIRC, RMS said that using signal like that was very unclean and using throw
>     would be cleaner.
> 
> That is the first thing I said.  Afterwards I agreed to a modified
> version of the change which avoids the ugliness at the Lisp level.

True, but as I read Stefan's comments, removing the ugliness at the
Lisp level comes at the expense of increased ugliness and decreased
functional correctness at the C level.

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-25  5:35                   ` while-no-input Richard Stallman
  2002-10-25  9:19                     ` while-no-input Kim F. Storm
@ 2002-10-25 13:44                     ` Stefan Monnier
  2002-10-26 20:13                       ` while-no-input Richard Stallman
  1 sibling, 1 reply; 32+ messages in thread
From: Stefan Monnier @ 2002-10-25 13:44 UTC (permalink / raw)
  Cc: storm, monnier+gnu/emacs, emacs-devel

>     IIRC, RMS said that using signal like that was very unclean and using
>     throw would be cleaner.
> 
> That is the first thing I said.  Afterwards I agreed to a modified
> version of the change which avoids the ugliness at the Lisp level.

I don't understand what you're referring to.
Are you saying that you did agree to a version that was not using `throw' ?
What ugliness at the Lisp level ?

I still have no idea what you mean by "ugly" in reference to my patch.
All it does is allow you to make normal keystrokes generate a quit event
and it also allows you to check which kind of quit event is generated
so you can tell the difference between a C-g quit and an any-key quit.

Using throw for such any-key quit sounds just plain wrong to me since
it is very much a `quit' like any other, that obeys inhibit-quit and
that aborts the current execution.

As I said, I'd probably settle for `throw' because I care more about
having the feature at all than about implementing it right (from my
point of view), but if I have to settle for `throw', it'll take me much
more time to get the patch ready/tested/installed, so someone else
might want to do it before me.


	Stefan

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-25 13:44                     ` while-no-input Stefan Monnier
@ 2002-10-26 20:13                       ` Richard Stallman
  2002-10-29 19:45                         ` while-no-input Stefan Monnier
  0 siblings, 1 reply; 32+ messages in thread
From: Richard Stallman @ 2002-10-26 20:13 UTC (permalink / raw)
  Cc: storm, monnier+gnu/emacs, emacs-devel

    I don't understand what you're referring to.
    Are you saying that you did agree to a version that was not using `throw' ?

I agreed to the version using `throw'.  That is what I was referring to.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-25  9:19                     ` while-no-input Kim F. Storm
@ 2002-10-26 20:15                       ` Richard Stallman
  0 siblings, 0 replies; 32+ messages in thread
From: Richard Stallman @ 2002-10-26 20:15 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, emacs-devel

    True, but as I read Stefan's comments, removing the ugliness at the
    Lisp level comes at the expense of increased ugliness and decreased
    functional correctness at the C level.

I don't think so.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-26 20:13                       ` while-no-input Richard Stallman
@ 2002-10-29 19:45                         ` Stefan Monnier
  2002-10-31 17:25                           ` while-no-input Richard Stallman
  0 siblings, 1 reply; 32+ messages in thread
From: Stefan Monnier @ 2002-10-29 19:45 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, storm, emacs-devel


Kim said:
>     IIRC, RMS said that using signal like that was very unclean and
>     using throw would be cleaner.

rms@gnu.org said:
> That is the first thing I said.  Afterwards I agreed to a modified
> version of the change which avoids the ugliness at the Lisp level. 

I then said:
>     I don't understand what you're referring to.
>     Are you saying that you did agree to a version that was not using `throw' ?

To which you now reply:
> I agreed to the version using `throw'.  That is what I was referring to.

Could you explain what is unclean about using `signal' ?
Currently, the only non-local exit that ever happens "asynchronously"
is the quit signal and it's also the only thing that obeys the
inhibit-quit flag.  The feature I'd like to introduce is also
an asynchonous non-local exit and should also obey the inhibit-quit
flag, so it seems eminently natural to use a quit signal as well.

The fact that the implementation is easier this way is just
reflects the fact that it is the "right" approach.


	Stefan

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-29 19:45                         ` while-no-input Stefan Monnier
@ 2002-10-31 17:25                           ` Richard Stallman
  2002-10-31 18:03                             ` while-no-input Stefan Monnier
  0 siblings, 1 reply; 32+ messages in thread
From: Richard Stallman @ 2002-10-31 17:25 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, storm, emacs-devel

    Could you explain what is unclean about using `signal' ?

I already did.  Error handling primitives should not be used for
normal occurrences that are not errors.

I don't have time for more discussion of this--sorry.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-31 17:25                           ` while-no-input Richard Stallman
@ 2002-10-31 18:03                             ` Stefan Monnier
  2002-11-02  3:32                               ` while-no-input Richard Stallman
  0 siblings, 1 reply; 32+ messages in thread
From: Stefan Monnier @ 2002-10-31 18:03 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, storm, emacs-devel

>     Could you explain what is unclean about using `signal' ?
> 
> I already did.  Error handling primitives should not be used for
> normal occurrences that are not errors.

Huh?  Than what about C-g ?
Doesn't look like an error to me any more than "hit any key to abort" does.


	Stefan

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2002-10-31 18:03                             ` while-no-input Stefan Monnier
@ 2002-11-02  3:32                               ` Richard Stallman
  0 siblings, 0 replies; 32+ messages in thread
From: Richard Stallman @ 2002-11-02  3:32 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, storm, emacs-devel

C-g is pretty much like an error even if not exactly.
Quitting is not an anomaly, but it is not normal.
The arrival of more input is normal.

Please don't ask me to spend more time on this.  I have lots of other
work to do, and I've made the decision.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* while-no-input
  2004-11-26 11:44 ` Kim F. Storm
@ 2004-11-27 18:51   ` Richard Stallman
  2004-11-27 23:03     ` while-no-input Kim F. Storm
  0 siblings, 1 reply; 32+ messages in thread
From: Richard Stallman @ 2004-11-27 18:51 UTC (permalink / raw)
  Cc: emacs-devel, monnier, klaus.berndl

    Current state is that RMS rejected Stefan's implementation of while-no-input.

    No further progress was made, as Stefan didn't want to pursue the
    issue further and I didn't quite understand how RMS wanted to
    implement it using a signal.

I don't remember the discussion, but if you tell me what month it was,
I can search for the messages.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2004-11-27 18:51   ` while-no-input Richard Stallman
@ 2004-11-27 23:03     ` Kim F. Storm
  2004-11-29  6:11       ` while-no-input Richard Stallman
  0 siblings, 1 reply; 32+ messages in thread
From: Kim F. Storm @ 2004-11-27 23:03 UTC (permalink / raw)
  Cc: emacs-devel, monnier, klaus.berndl

Richard Stallman <rms@gnu.org> writes:

>     Current state is that RMS rejected Stefan's implementation of while-no-input.
>
>     No further progress was made, as Stefan didn't want to pursue the
>     issue further and I didn't quite understand how RMS wanted to
>     implement it using a signal.
>
> I don't remember the discussion, but if you tell me what month it was,
> I can search for the messages.

October/November 2002


-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2004-11-27 23:03     ` while-no-input Kim F. Storm
@ 2004-11-29  6:11       ` Richard Stallman
  2004-11-29 14:20         ` while-no-input Stefan Monnier
  0 siblings, 1 reply; 32+ messages in thread
From: Richard Stallman @ 2004-11-29  6:11 UTC (permalink / raw)
  Cc: emacs-devel, monnier, klaus.berndl

Here's where the discussion ended up:

    The problem is that we need while-no-input to be able to encapsulate
    _UNMODIFIED_ code (such as ange-ftp and tramp) so that user input
    transparently "interrupts" (or quits) that code.

    Obviously, the code we need to encapsulate must already have been
    written to intercept the "quit" signal to be able to properly clean-up
    network connections etc. due to a keyboard-quit.

    Therefore, the most obvious solution -- once you see it -- to
    implement while-no-input is to use the quit signal as an indication
    of pending user input.  That way, the existing code to handle
    the quit signal will make while-no-input work transparently out of
    the box!


    In contrast, using throw/catch instead of Stefan's `annotated' quit
    signal _DOES_NOT_WORK_ since the code we really want to encapsulate,
    such as ange-ftp and tramp, is not written to expect a non-local exit
    due to non-quit events!

I doubt that argument.  Usually the way to arrange to clean something
up is with unwind-protect, and that will handle any nonlocal exit.
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
there is really no advantage in using signals.

Can you find any real code where using a quit signal would work better
than using throw?

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2004-11-29  6:11       ` while-no-input Richard Stallman
@ 2004-11-29 14:20         ` Stefan Monnier
  2004-11-30  7:03           ` while-no-input Richard Stallman
  0 siblings, 1 reply; 32+ messages in thread
From: Stefan Monnier @ 2004-11-29 14:20 UTC (permalink / raw)
  Cc: klaus.berndl, emacs-devel, Kim F. Storm

> 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
since it also causes non-local exits at places where it can't be predited
(just like quit).
Don't forget that the code within while-no-input is usually code that was
not specifically designed for while-no-input (otherwise it would already use
input-pending-p instead).

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.  `while-no-input'
introduces another form of asynchronous signalling and is thus much more
like `quit' than like `throw'.


        Stefan

^ permalink raw reply	[flat|nested] 32+ messages in thread

* RE: while-no-input
@ 2004-11-29 14:30 klaus.berndl
  2004-11-29 14:55 ` while-no-input Stefan Monnier
  0 siblings, 1 reply; 32+ messages in thread
From: klaus.berndl @ 2004-11-29 14:30 UTC (permalink / raw)
  Cc: emacs-devel, storm

Stefan Monnier wrote:
>> 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 since it also causes non-local exits at places where it
> can't be predited (just like quit).
> Don't forget that the code within while-no-input is usually code that
> was not specifically designed for while-no-input (otherwise it would
> already use input-pending-p instead).

Hmm, are you sure about that??
IMHO the code within while-no-input can also be code which would use
input-pending-p already, so my example with performing a VC-state-check
for a set of files which i want to be interruptable by the user at EVERY
timepoint.... with only input-pending-p i can only interrupt directly before
the next VC-state-check, because the call `vc-state' rsp. `vc-recompute-state'
is not interruptable unless by hitting quit... 

But if i could encapsulate processing my set of files in your while-no-input
macro then it could be interrupted at EVERY timepoint, if i have understood
you right, because this would also interrupt the inner state-check-function,
wouldn't it?

So i would do

(while-no-input ....
  (unwind-protect
  ;; checvk the state for the set of files in BODYFORM
    ( ;; cleanup whatever is to clean up
     ))

Have i understodd this right?

> 
> 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. 
> `while-no-input' introduces another form of asynchronous signalling
> and is thus much more like `quit' than like `throw'.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2004-11-29 14:30 while-no-input klaus.berndl
@ 2004-11-29 14:55 ` Stefan Monnier
  0 siblings, 0 replies; 32+ messages in thread
From: Stefan Monnier @ 2004-11-29 14:55 UTC (permalink / raw)
  Cc: emacs-devel, rms, storm

>> Don't forget that the code within while-no-input is usually code that
>> was not specifically designed for while-no-input (otherwise it would
>> already use input-pending-p instead).

> Hmm, are you sure about that??

About what?

> IMHO the code within while-no-input can also be code which would use
> input-pending-p already, so my example with performing a VC-state-check

I never said otherwise, did I?


        Stefan

^ permalink raw reply	[flat|nested] 32+ messages in thread

* RE: while-no-input
@ 2004-11-29 15:02 klaus.berndl
  0 siblings, 0 replies; 32+ messages in thread
From: klaus.berndl @ 2004-11-29 15:02 UTC (permalink / raw)
  Cc: rms, storm

Stefan Monnier wrote:
>>> Don't forget that the code within while-no-input is usually code
>>> that was not specifically designed for while-no-input (otherwise it
>>> would already use input-pending-p instead).
> 
>> Hmm, are you sure about that??
> 
> About what?

about "that the code within while-no-input is usually code that
was not specifically designed for while-no-input (otherwise it would
already use input-pending-p instead)"... but it seems that i have
misunderstood your latest posting....

> 
>> IMHO the code within while-no-input can also be code which would use
>> input-pending-p already, so my example with performing a
>> VC-state-check 
> 
> I never said otherwise, did I?
> 
> 
>         Stefan

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2004-11-29 14:20         ` while-no-input Stefan Monnier
@ 2004-11-30  7:03           ` Richard Stallman
  2004-11-30 14:56             ` while-no-input Kim F. Storm
  0 siblings, 1 reply; 32+ messages in thread
From: Richard Stallman @ 2004-11-30  7:03 UTC (permalink / raw)
  Cc: klaus.berndl, emacs-devel, storm

    > 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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: while-no-input
  2004-11-30  7:03           ` while-no-input Richard Stallman
@ 2004-11-30 14:56             ` Kim F. Storm
  0 siblings, 0 replies; 32+ messages in thread
From: Kim F. Storm @ 2004-11-30 14:56 UTC (permalink / raw)
  Cc: emacs-devel, Stefan Monnier, klaus.berndl

Richard Stallman <rms@gnu.org> writes:

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

I tried it -- but I don't have SYNC_INPUT defined, so I used this:

#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);				\
      }							\
  } while (0)


I then ran this code (in my normal emacs with cua-mode enabled):

(while-no-input
  (while t
    (prin1 "x")
    (sit-for 0)))

and hit space after a few seconds.  Got a crash:


Breakpoint 1, abort () at emacs.c:442

(gdb) xbacktrace
"cua--post-command-handler"
"run-hooks"
(gdb) bt
#0  abort () at emacs.c:442
#1  0x08182ae9 in Feval (form=140121845) at eval.c:2015
#2  0x081819e0 in Fcondition_case (args=145132605) at eval.c:1329
#3  0x081b7204 in Fbyte_code (bytestr=144710763, vector=144806556, maxdepth=24) at bytecode.c:864
#4  0x08184383 in funcall_lambda (fun=144661804, nargs=0, arg_vector=0xbfffd608) at eval.c:2959
#5  0x08183dcb in Ffuncall (nargs=1, args=0xbfffd604) at eval.c:2820
#6  0x081836c8 in run_hook_with_args (nargs=1, args=0xbfffd604, cond=to_completion) at eval.c:2440
#7  0x081834bc in Frun_hooks (nargs=1, args=0xbfffd6d4) at eval.c:2308
#8  0x08183b46 in Ffuncall (nargs=2, args=0xbfffd6d0) at eval.c:2753
#9  0x0818386b in call1 (fn=137798905, arg1=137754665) at eval.c:2566
#10 0x0810cf01 in safe_run_hooks_1 (hook=0) at keyboard.c:2034
#11 0x08181b06 in internal_condition_case (bfun=0x810cee7 <safe_run_hooks_1>, handlers=137698537, hfun=0x810cf06 <safe_run_hooks_error>) at eval.c:1382
#12 0x0810cf9c in safe_run_hooks (hook=137754665) at keyboard.c:2062
#13 0x0810c25b in command_loop_1 () at keyboard.c:1801
#14 0x08181b06 in internal_condition_case (bfun=0x810adbb <command_loop_1>, handlers=137764305, hfun=0x810a900 <cmd_error>) at eval.c:1382
#15 0x0810ac33 in command_loop_2 () at keyboard.c:1309
#16 0x081815cc in internal_catch (tag=137756753, func=0x810ac14 <command_loop_2>, arg=137698489) at eval.c:1143
#17 0x0810abe6 in command_loop () at keyboard.c:1288
#18 0x0810a67f in recursive_edit_1 () at keyboard.c:981
#19 0x0810a7c0 in Frecursive_edit () at keyboard.c:1042
#20 0x0810911b in main (argc=3, argv=0xbfffdf04) at emacs.c:1742
#21 0x42015574 in __libc_start_main () from /lib/tls/libc.so.6
(gdb) p handling_signal
$1 = 1
(gdb) p interrupt_input_blocked
$2 = 0
(gdb) 

Seems that we can break out of XTread_socket without restoring
handling_signal.

I don't know if it is sufficient to unwind protect it.


-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2004-11-30 14:56 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-11-29 14:30 while-no-input klaus.berndl
2004-11-29 14:55 ` while-no-input Stefan Monnier
  -- strict thread matches above, loose matches on Subject: below --
2004-11-29 15:02 while-no-input klaus.berndl
2004-11-26  9:26 AW: vc-state always calls heuristic function klaus.berndl
2004-11-26 11:44 ` Kim F. Storm
2004-11-27 18:51   ` while-no-input Richard Stallman
2004-11-27 23:03     ` while-no-input Kim F. Storm
2004-11-29  6:11       ` while-no-input Richard Stallman
2004-11-29 14:20         ` while-no-input Stefan Monnier
2004-11-30  7:03           ` while-no-input Richard Stallman
2004-11-30 14:56             ` while-no-input Kim F. Storm
2002-10-01 21:19 while-no-input Stefan Monnier
2002-10-02 19:24 ` while-no-input Richard Stallman
2002-10-02 21:43   ` while-no-input Stefan Monnier
2002-10-03 13:28     ` while-no-input Richard Stallman
2002-10-03 15:53       ` while-no-input Stefan Monnier
2002-10-03 22:44         ` while-no-input Kim F. Storm
2002-10-03 22:33           ` while-no-input Stefan Monnier
2002-10-04 15:46         ` while-no-input Richard Stallman
2002-10-04 15:59           ` while-no-input Stefan Monnier
2002-10-05 16:33             ` while-no-input Richard Stallman
2002-10-24  0:06             ` while-no-input Kim F. Storm
2002-10-24  7:20               ` while-no-input Stefan Monnier
2002-10-24 10:24                 ` while-no-input Kim F. Storm
2002-10-25  5:35                   ` while-no-input Richard Stallman
2002-10-25  9:19                     ` while-no-input Kim F. Storm
2002-10-26 20:15                       ` while-no-input Richard Stallman
2002-10-25 13:44                     ` while-no-input Stefan Monnier
2002-10-26 20:13                       ` while-no-input Richard Stallman
2002-10-29 19:45                         ` while-no-input Stefan Monnier
2002-10-31 17:25                           ` while-no-input Richard Stallman
2002-10-31 18:03                             ` while-no-input Stefan Monnier
2002-11-02  3:32                               ` while-no-input Richard Stallman
2002-10-05 22:43       ` while-no-input Kim F. Storm

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).