From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: "Stefan Monnier" Newsgroups: gmane.emacs.devel Subject: while-no-input Date: Tue, 01 Oct 2002 17:19:32 -0400 Sender: emacs-devel-admin@gnu.org Message-ID: <200210012119.g91LJW922045@rum.cs.yale.edu> NNTP-Posting-Host: localhost.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: main.gmane.org 1033507265 11016 127.0.0.1 (1 Oct 2002 21:21:05 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Tue, 1 Oct 2002 21:21:05 +0000 (UTC) Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 17wUS0-0002rW-00 for ; Tue, 01 Oct 2002 23:21:04 +0200 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 17wVCL-0002v6-00 for ; Wed, 02 Oct 2002 00:08:57 +0200 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.10) id 17wUSG-0008OJ-00; Tue, 01 Oct 2002 17:21:20 -0400 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.10) id 17wUQZ-0008KC-00 for emacs-devel@gnu.org; Tue, 01 Oct 2002 17:19:35 -0400 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.10) id 17wUQX-0008JR-00 for emacs-devel@gnu.org; Tue, 01 Oct 2002 17:19:34 -0400 Original-Received: from rum.cs.yale.edu ([128.36.229.169]) by monty-python.gnu.org with esmtp (Exim 4.10) id 17wUQX-0008JN-00 for emacs-devel@gnu.org; Tue, 01 Oct 2002 17:19:33 -0400 Original-Received: (from monnier@localhost) by rum.cs.yale.edu (8.11.6/8.11.6) id g91LJW922045; Tue, 1 Oct 2002 17:19:32 -0400 X-Mailer: exmh version 2.4 06/23/2000 with nmh-1.0.4 Original-To: emacs-devel@gnu.org Errors-To: emacs-devel-admin@gnu.org X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.0.11 Precedence: bulk List-Help: List-Post: List-Subscribe: , List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: Xref: main.gmane.org gmane.emacs.devel:8310 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:8310 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