* while-no-input interrupted by *shell* @ 2018-09-24 15:24 Michael Heerdegen 2018-09-24 16:14 ` Eli Zaretskii ` (2 more replies) 0 siblings, 3 replies; 42+ messages in thread From: Michael Heerdegen @ 2018-09-24 15:24 UTC (permalink / raw) To: Emacs Development Hello, I found another annoyance with `while-no-input': If you have a *shell* buffer producing output - for example run something like ls -R in *shell* - then `while-no-input' is obviously interrupted by what's going on there. For example (while-no-input (sit-for 100)) immediately terminates when evaluated while such a shell buffer exists. Is this expected, and is there a way to avoid this behavior? Thanks, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-24 15:24 while-no-input interrupted by *shell* Michael Heerdegen @ 2018-09-24 16:14 ` Eli Zaretskii 2018-09-24 16:40 ` Stefan Monnier ` (2 more replies) 2018-09-24 16:19 ` Stefan Monnier 2018-09-25 17:47 ` while-no-input and pending input (was: while-no-input interrupted by *shell*) Michael Heerdegen 2 siblings, 3 replies; 42+ messages in thread From: Eli Zaretskii @ 2018-09-24 16:14 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Date: Mon, 24 Sep 2018 17:24:47 +0200 > > I found another annoyance with `while-no-input': If you have a *shell* > buffer producing output - for example run something like ls -R in > *shell* - then `while-no-input' is obviously interrupted by what's going > on there. For example > > (while-no-input (sit-for 100)) > > immediately terminates when evaluated while such a shell buffer exists. > > Is this expected, and is there a way to avoid this behavior? Is it while-no-input that returns immediately, or is it sit-for? ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-24 16:14 ` Eli Zaretskii @ 2018-09-24 16:40 ` Stefan Monnier 2018-09-24 17:00 ` Eli Zaretskii 2018-09-24 17:39 ` Michael Heerdegen 2018-09-24 21:23 ` while-no-input interrupted by *shell* Andreas Schwab 2 siblings, 1 reply; 42+ messages in thread From: Stefan Monnier @ 2018-09-24 16:40 UTC (permalink / raw) To: emacs-devel >> (while-no-input (sit-for 100)) > Is it while-no-input that returns immediately, or is it sit-for? Oh, good point, I skipped the body of the while-no-input and hence didn't notice the sit-for. This said, the bulk of my answer isn't affected: sit-for shouldn't be interrupted by subprocess output either, I think. Stefan ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-24 16:40 ` Stefan Monnier @ 2018-09-24 17:00 ` Eli Zaretskii 2018-09-24 18:35 ` Stefan Monnier 0 siblings, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-09-24 17:00 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Mon, 24 Sep 2018 12:40:39 -0400 > > This said, the bulk of my answer isn't affected: sit-for shouldn't be > interrupted by subprocess output either, I think. Really? I think sit-for is expected to stop waiting when we read something from a subprocess; sleep-for makes a point of restarting the wait when that happens. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-24 17:00 ` Eli Zaretskii @ 2018-09-24 18:35 ` Stefan Monnier 2018-09-24 18:48 ` Eli Zaretskii 0 siblings, 1 reply; 42+ messages in thread From: Stefan Monnier @ 2018-09-24 18:35 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel >> This said, the bulk of my answer isn't affected: sit-for shouldn't be >> interrupted by subprocess output either, I think. > Really? I think sit-for is expected to stop waiting when we read > something from a subprocess; Hmm... Really? I'm not sure what's really the ideal behavior, nor what we've done historically, but it seems undesirable to pay attention to subprocess output (in general subprocess output is unrelated to the Elisp calling sit-for). I thought accept-process-output waits for subprocess output and sit-for waits for input events (and we don't have any direct fonction to wait for both at the same time). Stefan ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-24 18:35 ` Stefan Monnier @ 2018-09-24 18:48 ` Eli Zaretskii 0 siblings, 0 replies; 42+ messages in thread From: Eli Zaretskii @ 2018-09-24 18:48 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: emacs-devel@gnu.org > Date: Mon, 24 Sep 2018 14:35:50 -0400 > > I thought accept-process-output waits for subprocess output and sit-for > waits for input events (and we don't have any direct fonction to wait for both > at the same time). The commentary to wait_reading_process_output tells a different story: Return positive if we received input from WAIT_PROC (or from any process if WAIT_PROC is null), zero if we attempted to receive input but got none, and negative if we didn't even try. */ ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-24 16:14 ` Eli Zaretskii 2018-09-24 16:40 ` Stefan Monnier @ 2018-09-24 17:39 ` Michael Heerdegen 2018-09-24 18:00 ` Eli Zaretskii ` (2 more replies) 2018-09-24 21:23 ` while-no-input interrupted by *shell* Andreas Schwab 2 siblings, 3 replies; 42+ messages in thread From: Michael Heerdegen @ 2018-09-24 17:39 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > Is it while-no-input that returns immediately, or is it sit-for? If I repeat the recipe with only `sit-for', I get no interrupt, so `w-n-i' seems involved. I started ls -R in *shell* and evaluated (progn (sit-for 100) (message "!!!")) The *shell* buffer got still filled, but the !!! message only appeared after I had hit a key. Is a bug report justified? Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-24 17:39 ` Michael Heerdegen @ 2018-09-24 18:00 ` Eli Zaretskii 2018-09-24 19:09 ` Michael Heerdegen 2018-09-24 19:06 ` Stefan Monnier 2018-09-25 13:09 ` Eli Zaretskii 2 siblings, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-09-24 18:00 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: emacs-devel@gnu.org > Date: Mon, 24 Sep 2018 19:39:48 +0200 > > > Is it while-no-input that returns immediately, or is it sit-for? > > If I repeat the recipe with only `sit-for', I get no interrupt, so > `w-n-i' seems involved. What do you mean by "no interrupt"? > I started ls -R in *shell* and evaluated > > (progn (sit-for 100) > (message "!!!")) > > The *shell* buffer got still filled, but the !!! message only appeared > after I had hit a key. > > Is a bug report justified? It cannot hurt, especially if you could come up with a convenient reproducer. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-24 18:00 ` Eli Zaretskii @ 2018-09-24 19:09 ` Michael Heerdegen 0 siblings, 0 replies; 42+ messages in thread From: Michael Heerdegen @ 2018-09-24 19:09 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > > If I repeat the recipe with only `sit-for', I get no interrupt, so > > `w-n-i' seems involved. > > What do you mean by "no interrupt"? That `sit-for' doesn't prematurely terminate. Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-24 17:39 ` Michael Heerdegen 2018-09-24 18:00 ` Eli Zaretskii @ 2018-09-24 19:06 ` Stefan Monnier 2018-09-25 13:09 ` Eli Zaretskii 2 siblings, 0 replies; 42+ messages in thread From: Stefan Monnier @ 2018-09-24 19:06 UTC (permalink / raw) To: emacs-devel > (progn (sit-for 100) > (message "!!!")) > > The *shell* buffer got still filled, but the !!! message only appeared > after I had hit a key. FWIW, that looks correct to me. Eli seems to disagree, so it shows that this part of the semantics of sit-for is murky. Stefan ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-24 17:39 ` Michael Heerdegen 2018-09-24 18:00 ` Eli Zaretskii 2018-09-24 19:06 ` Stefan Monnier @ 2018-09-25 13:09 ` Eli Zaretskii 2018-09-25 13:39 ` Michael Heerdegen 2018-09-25 15:25 ` BUFFER_SWITCH_EVENT (was: while-no-input interrupted by *shell*) Stefan Monnier 2 siblings, 2 replies; 42+ messages in thread From: Eli Zaretskii @ 2018-09-25 13:09 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Date: Mon, 24 Sep 2018 19:39:48 +0200 > Cc: emacs-devel@gnu.org > > Eli Zaretskii <eliz@gnu.org> writes: > > > Is it while-no-input that returns immediately, or is it sit-for? > > If I repeat the recipe with only `sit-for', I get no interrupt, so > `w-n-i' seems involved. > > I started ls -R in *shell* and evaluated > > (progn (sit-for 100) > (message "!!!")) > > The *shell* buffer got still filled, but the !!! message only appeared > after I had hit a key. It's while-no-input that returns prematurely, indeed. When output from a subprocess arrives, we insert a buffer-switch event into the input queue, and that counts as input. Therefater, any code that calls maybe_quit will cause while-no-input to throw. The backtrace which shows that is below, for the record. Here's a patch, comments welcome. diff --git a/lisp/subr.el b/lisp/subr.el index 7582b6c..59f6949 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3542,7 +3542,7 @@ with-local-quit ;; Don't throw `throw-on-input' on those events by default. (setq while-no-input-ignore-events '(focus-in focus-out help-echo iconify-frame - make-frame-visible selection-request)) + make-frame-visible selection-request buffer-switch)) (defmacro while-no-input (&rest body) "Execute BODY only as long as there's no pending input. diff --git a/src/keyboard.c b/src/keyboard.c index 1da5ac0..0d56ea3 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -3569,6 +3569,7 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event, case ICONIFY_EVENT: ignore_event = Qiconify_frame; break; case DEICONIFY_EVENT: ignore_event = Qmake_frame_visible; break; case SELECTION_REQUEST_EVENT: ignore_event = Qselection_request; break; + case BUFFER_SWITCH_EVENT: ignore_event = Qbuffer_switch; break; default: ignore_event = Qnil; break; } @@ -11104,6 +11105,8 @@ syms_of_keyboard (void) /* Menu and tool bar item parts. */ DEFSYM (Qmenu_enable, "menu-enable"); + DEFSYM (Qbuffer_switch, "buffer-switch"); + #ifdef HAVE_NTGUI DEFSYM (Qlanguage_change, "language-change"); DEFSYM (Qend_session, "end-session"); Here's the backtrace I promised: #0 kbd_buffer_store_buffered_event (event=0x82ad78, hold_quit=0x0) at keyboard.c:3579 #1 0x01154d53 in kbd_buffer_store_event_hold (event=0x82ad78, hold_quit=0x0) at keyboard.h:472 #2 0x011643b5 in kbd_buffer_store_event (event=0x0) at keyboard.c:3439 #3 0x0116dd10 in record_asynch_buffer_change () at keyboard.c:6866 #4 0x012bcb86 in read_and_dispose_of_process_output ( p=0x1c35c68 <dumped_data+4772424>, chars=0x82ae68 "0.win32.zip\r\n-rw-rw-rw- 1 Zaretzky None "..., nbytes=4096, coding=0xfc66b8) at process.c:6049 #5 0x012bc69d in read_process_output (proc=XIL(0xa000000001c35c68), channel=5) at process.c:5937 #6 0x012bb670 in wait_reading_process_output (time_limit=100, nsecs=0, read_kbd=-1, do_display=true, wait_for_cell=XIL(0), wait_proc=0x0, just_wait_proc=0) at process.c:5624 #7 0x01164d76 in kbd_buffer_get_event (kbp=0x82c434, used_mouse_menu=0x0, end_time=0x82c9d8) at keyboard.c:3810 #8 0x0115e58c in read_event_from_main_queue (end_time=0x82c9d8, local_getcjmp=0x82c850, used_mouse_menu=0x0) at keyboard.c:2151 #9 0x0115ea7b in read_decoded_event_from_main_queue (end_time=0x82c9d8, local_getcjmp=0x82c850, prev_event=XIL(0), used_mouse_menu=0x0) at keyboard.c:2214 #10 0x0116112a in read_char (commandflag=0, map=XIL(0), prev_event=XIL(0), used_mouse_menu=0x0, end_time=0x82c9d8) at keyboard.c:2802 #11 0x0127e631 in read_filtered_event (no_switch_frame=false, ascii_required=false, error_nonascii=false, input_method=true, seconds=make_number(100)) at lread.c:672 #12 0x0127ec54 in Fread_event (prompt=XIL(0), inherit_input_method=XIL(0xebd0), seconds=make_number(100)) at lread.c:788 #13 0x0123c0d9 in funcall_subr (subr=0x16a8ee0 <Sread_event>, numargs=3, args=0x82cc38) at eval.c:2853 #14 0x0123ba8d in Ffuncall (nargs=4, args=0x82cc30) at eval.c:2773 #15 0x012a700b in exec_byte_code (bytestr=XIL(0x80000000013bc928), vector=XIL(0xa0000000013bc938), maxdepth=make_number(7), args_template=make_number(769), nargs=1, args=0x82d148) at bytecode.c:629 #16 0x0123cbef in funcall_lambda (fun=XIL(0xa0000000013bc8f8), nargs=1, arg_vector=0x82d140) at eval.c:2974 #17 0x0123c6bc in apply_lambda (fun=XIL(0xa0000000013bc8f8), args=XIL(0xc00000000744f0a0), count=20) at eval.c:2910 #18 0x01239be8 in eval_sub (form=XIL(0xc00000000744f090)) at eval.c:2283 #19 0x01231641 in Fprogn (body=XIL(0)) at eval.c:459 #20 0x01239140 in eval_sub (form=XIL(0xc00000000744d340)) at eval.c:2190 #21 0x01230f6d in For (args=XIL(0)) at eval.c:372 #22 0x01239140 in eval_sub (form=XIL(0xc00000000744d370)) at eval.c:2190 #23 0x01231641 in Fprogn (body=XIL(0)) at eval.c:459 #24 0x01234854 in Flet (args=XIL(0xc00000000744d390)) at eval.c:973 #25 0x01239140 in eval_sub (form=XIL(0xc00000000744d3a0)) at eval.c:2190 #26 0x01231641 in Fprogn (body=XIL(0)) at eval.c:459 #27 0x01234fa3 in internal_catch (tag=XIL(0x5c6bd88), func=0x123153f <Fprogn>, arg=XIL(0xc00000000744d3b0)) at eval.c:1101 #28 0x01234f42 in Fcatch (args=XIL(0xc00000000744d3c0)) at eval.c:1078 #29 0x01239140 in eval_sub (form=XIL(0xc00000000744d3d0)) at eval.c:2190 #30 0x01231641 in Fprogn (body=XIL(0)) at eval.c:459 #31 0x01234854 in Flet (args=XIL(0xc00000000744cc30)) at eval.c:973 #32 0x01239140 in eval_sub (form=XIL(0xc00000000744cc40)) at eval.c:2190 #33 0x01235e05 in internal_lisp_condition_case (var=XIL(0), bodyform=XIL(0xc00000000744cc40), handlers=XIL(0xc0000000013bf1e0)) at eval.c:1307 #34 0x0123566b in Fcondition_case (args=XIL(0xc00000000744cc60)) at eval.c:1231 #35 0x01239140 in eval_sub (form=XIL(0xc00000000744cc70)) at eval.c:2190 #36 0x01238929 in Feval (form=XIL(0xc00000000744cc70), lexical=XIL(0)) at eval.c:2058 #37 0x0123c097 in funcall_subr (subr=0x16a79a0 <Seval>, numargs=2, args=0x82e420) at eval.c:2850 #38 0x0123ba8d in Ffuncall (nargs=3, args=0x82e418) at eval.c:2773 #39 0x012a700b in exec_byte_code (bytestr=XIL(0x80000000014467d8), vector=XIL(0xa0000000014467e8), maxdepth=make_number(10), args_template=make_number(1025), nargs=4, args=0x82eb80) at bytecode.c:629 #40 0x0123cbef in funcall_lambda (fun=XIL(0xa000000001446798), nargs=4, arg_vector=0x82eb60) at eval.c:2974 #41 0x0123bae7 in Ffuncall (nargs=5, args=0x82eb58) at eval.c:2775 #42 0x0122cbe4 in Ffuncall_interactively (nargs=5, args=0x82eb58) at callint.c:252 #43 0x0123bf84 in funcall_subr (subr=0x16a75c0 <Sfuncall_interactively>, numargs=5, args=0x82eb58) at eval.c:2828 #44 0x0123ba8d in Ffuncall (nargs=6, args=0x82eb50) at eval.c:2773 #45 0x0123a621 in Fapply (nargs=3, args=0x82eda8) at eval.c:2393 #46 0x0122d435 in Fcall_interactively (function=XIL(0x120108), record_flag=XIL(0), keys=XIL(0xa000000001becb98)) at callint.c:389 #47 0x0123c0d9 in funcall_subr (subr=0x16a75e0 <Scall_interactively>, numargs=3, args=0x82f000) at eval.c:2853 #48 0x0123ba8d in Ffuncall (nargs=4, args=0x82eff8) at eval.c:2773 #49 0x012a700b in exec_byte_code (bytestr=XIL(0x8000000001447618), vector=XIL(0xa000000001447628), maxdepth=make_number(13), args_template=make_number(1025), nargs=1, args=0x82f620) at bytecode.c:629 #50 0x0123cbef in funcall_lambda (fun=XIL(0xa0000000014475e8), nargs=1, arg_vector=0x82f618) at eval.c:2974 #51 0x0123bae7 in Ffuncall (nargs=2, args=0x82f610) at eval.c:2775 #52 0x0123af8c in call1 (fn=XIL(0x4398), arg1=XIL(0x120108)) at eval.c:2624 #53 0x0115bbf5 in command_loop_1 () at keyboard.c:1482 #54 0x01235ea4 in internal_condition_case (bfun=0x115afb0 <command_loop_1>, handlers=XIL(0x5b70), hfun=0x115a1dc <cmd_error>) at eval.c:1336 #55 0x0115aa1d in command_loop_2 (ignore=XIL(0)) at keyboard.c:1110 #56 0x01234fa3 in internal_catch (tag=XIL(0xf570), func=0x115a9e1 <command_loop_2>, arg=XIL(0)) at eval.c:1101 #57 0x0115a99c in command_loop () at keyboard.c:1089 #58 0x01159c08 in recursive_edit_1 () at keyboard.c:695 #59 0x01159eb2 in Frecursive_edit () at keyboard.c:766 #60 0x01157494 in main (argc=2, argv=0xa428d8) at emacs.c:1715 Lisp Backtrace: "read-event" (0x82cc38) "sit-for" (0x82d140) "progn" (0x82d4f8) "or" (0x82d6c8) "let" (0x82d998) "catch" (0x82dc08) "let" (0x82ded8) "condition-case" (0x82e1a8) "eval" (0x82e420) "eval-expression" (0x82eb60) "funcall-interactively" (0x82eb58) "call-interactively" (0x82f000) "command-execute" (0x82f618) ^ permalink raw reply related [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-25 13:09 ` Eli Zaretskii @ 2018-09-25 13:39 ` Michael Heerdegen 2018-09-25 14:14 ` Eli Zaretskii 2018-09-25 15:25 ` BUFFER_SWITCH_EVENT (was: while-no-input interrupted by *shell*) Stefan Monnier 1 sibling, 1 reply; 42+ messages in thread From: Michael Heerdegen @ 2018-09-25 13:39 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > Here's a patch, comments welcome. That works, it solves my original problem. It's also what I had tried if I could write C, which is not the case. Thanks, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-25 13:39 ` Michael Heerdegen @ 2018-09-25 14:14 ` Eli Zaretskii 2018-09-29 7:13 ` Eli Zaretskii 0 siblings, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-09-25 14:14 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: emacs-devel@gnu.org > Date: Tue, 25 Sep 2018 15:39:41 +0200 > > Eli Zaretskii <eliz@gnu.org> writes: > > > Here's a patch, comments welcome. > > That works, it solves my original problem. It's also what I had tried > if I could write C, which is not the case. Thanks for testing. I'm now wondering whether some code out there could depend on the current behavior. Because it looks like Emacs behaved like that at least since v22.1, probably earlier. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-25 14:14 ` Eli Zaretskii @ 2018-09-29 7:13 ` Eli Zaretskii 0 siblings, 0 replies; 42+ messages in thread From: Eli Zaretskii @ 2018-09-29 7:13 UTC (permalink / raw) To: michael_heerdegen; +Cc: emacs-devel > Date: Tue, 25 Sep 2018 17:14:40 +0300 > From: Eli Zaretskii <eliz@gnu.org> > Cc: emacs-devel@gnu.org > > > From: Michael Heerdegen <michael_heerdegen@web.de> > > Cc: emacs-devel@gnu.org > > Date: Tue, 25 Sep 2018 15:39:41 +0200 > > > > Eli Zaretskii <eliz@gnu.org> writes: > > > > > Here's a patch, comments welcome. > > > > That works, it solves my original problem. It's also what I had tried > > if I could write C, which is not the case. > > Thanks for testing. > > I'm now wondering whether some code out there could depend on the > current behavior. Because it looks like Emacs behaved like that at > least since v22.1, probably earlier. No further comments, so I pushed this to the emacs-26 branch, including a recipe to get the old behavior, if some package needs that. ^ permalink raw reply [flat|nested] 42+ messages in thread
* BUFFER_SWITCH_EVENT (was: while-no-input interrupted by *shell*) 2018-09-25 13:09 ` Eli Zaretskii 2018-09-25 13:39 ` Michael Heerdegen @ 2018-09-25 15:25 ` Stefan Monnier 2018-09-25 16:01 ` Eli Zaretskii 1 sibling, 1 reply; 42+ messages in thread From: Stefan Monnier @ 2018-09-25 15:25 UTC (permalink / raw) To: emacs-devel > When output from a subprocess arrives, we insert a buffer-switch event > into the input queue, and that counts as input. Therefater, any code > that calls maybe_quit will cause while-no-input to throw. The > backtrace which shows that is below, for the record. > Here's a patch, comments welcome. Looks good, thanks. I do wonder what these BUFFER_SWITCH_EVENT are for, tho. In record_asynch_buffer_change it says: /* We don't need a buffer-switch event unless Emacs is waiting for input. The purpose of the event is to make read_key_sequence look up the keymaps again. If we aren't in read_key_sequence, we don't need one, and the event could cause trouble by messing up (input-pending-p). Note: Fwaiting_for_user_input_p always returns nil when async subprocesses aren't supported. */ but I don't see why we'd need to look up the keymaps again. Stefan ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: BUFFER_SWITCH_EVENT (was: while-no-input interrupted by *shell*) 2018-09-25 15:25 ` BUFFER_SWITCH_EVENT (was: while-no-input interrupted by *shell*) Stefan Monnier @ 2018-09-25 16:01 ` Eli Zaretskii 2018-09-25 16:14 ` BUFFER_SWITCH_EVENT Stefan Monnier 0 siblings, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-09-25 16:01 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Tue, 25 Sep 2018 11:25:50 -0400 > > I do wonder what these BUFFER_SWITCH_EVENT are for, tho. > In record_asynch_buffer_change it says: > > /* We don't need a buffer-switch event unless Emacs is waiting for input. > The purpose of the event is to make read_key_sequence look up the > keymaps again. If we aren't in read_key_sequence, we don't need one, > and the event could cause trouble by messing up (input-pending-p). > Note: Fwaiting_for_user_input_p always returns nil when async > subprocesses aren't supported. */ > > but I don't see why we'd need to look up the keymaps again. To find buffer-local bindings? ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: BUFFER_SWITCH_EVENT 2018-09-25 16:01 ` Eli Zaretskii @ 2018-09-25 16:14 ` Stefan Monnier 2018-09-25 16:28 ` BUFFER_SWITCH_EVENT Eli Zaretskii 0 siblings, 1 reply; 42+ messages in thread From: Stefan Monnier @ 2018-09-25 16:14 UTC (permalink / raw) To: emacs-devel >> I do wonder what these BUFFER_SWITCH_EVENT are for, tho. >> In record_asynch_buffer_change it says: >> >> /* We don't need a buffer-switch event unless Emacs is waiting for input. >> The purpose of the event is to make read_key_sequence look up the >> keymaps again. If we aren't in read_key_sequence, we don't need one, >> and the event could cause trouble by messing up (input-pending-p). >> Note: Fwaiting_for_user_input_p always returns nil when async >> subprocesses aren't supported. */ >> >> but I don't see why we'd need to look up the keymaps again. > > To find buffer-local bindings? We already look them up presumably in the right place. I don't understand why we'd need to look them up again after running a process filter. Stefan ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: BUFFER_SWITCH_EVENT 2018-09-25 16:14 ` BUFFER_SWITCH_EVENT Stefan Monnier @ 2018-09-25 16:28 ` Eli Zaretskii 2018-09-25 17:19 ` BUFFER_SWITCH_EVENT Stefan Monnier 0 siblings, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-09-25 16:28 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Tue, 25 Sep 2018 12:14:37 -0400 > > >> but I don't see why we'd need to look up the keymaps again. > > > > To find buffer-local bindings? > > We already look them up presumably in the right place. I don't > understand why we'd need to look them up again after running > a process filter. Because a filter could have switched buffers, I presume. See this fragment of read_key_sequence: /* If the current buffer has been changed from under us, the keymap may have changed, so replay the sequence. */ if (BUFFERP (key)) { timer_resume_idle (); mock_input = t; /* Reset the current buffer from the selected window in case something changed the former and not the latter. This is to be more consistent with the behavior of the command_loop_1. */ if (fix_current_buffer) { if (! FRAME_LIVE_P (XFRAME (selected_frame))) Fkill_emacs (Qnil); if (XBUFFER (XWINDOW (selected_window)->contents) != current_buffer) Fset_buffer (XWINDOW (selected_window)->contents); } goto replay_sequence; } ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: BUFFER_SWITCH_EVENT 2018-09-25 16:28 ` BUFFER_SWITCH_EVENT Eli Zaretskii @ 2018-09-25 17:19 ` Stefan Monnier 2018-09-25 17:28 ` BUFFER_SWITCH_EVENT Eli Zaretskii 0 siblings, 1 reply; 42+ messages in thread From: Stefan Monnier @ 2018-09-25 17:19 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel >> >> but I don't see why we'd need to look up the keymaps again. >> > To find buffer-local bindings? >> We already look them up presumably in the right place. I don't >> understand why we'd need to look them up again after running >> a process filter. > Because a filter could have switched buffers, I presume. I don't follow: 1- we enter read-key-sequence 2- we read the set of keymaps 3- some process filter is executed, changing the current buffer 4- the set of keymaps that we need to use is still the same we computed at 2 and the keymaps themselves are also still the same What am I missing? Stefan ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: BUFFER_SWITCH_EVENT 2018-09-25 17:19 ` BUFFER_SWITCH_EVENT Stefan Monnier @ 2018-09-25 17:28 ` Eli Zaretskii 2018-09-25 18:14 ` BUFFER_SWITCH_EVENT Stefan Monnier 0 siblings, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-09-25 17:28 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: emacs-devel@gnu.org > Date: Tue, 25 Sep 2018 13:19:34 -0400 > > >> We already look them up presumably in the right place. I don't > >> understand why we'd need to look them up again after running > >> a process filter. > > Because a filter could have switched buffers, I presume. > > I don't follow: > > 1- we enter read-key-sequence > 2- we read the set of keymaps > 3- some process filter is executed, changing the current buffer > 4- the set of keymaps that we need to use is still the same we computed > at 2 and the keymaps themselves are also still the same > > What am I missing? You are asking the wrong guy, but I will try anyway: since the buffer changed, we need to replay the key sequence using the keymaps local to that buffer, not the ones we computed at 2. Right? ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: BUFFER_SWITCH_EVENT 2018-09-25 17:28 ` BUFFER_SWITCH_EVENT Eli Zaretskii @ 2018-09-25 18:14 ` Stefan Monnier 2018-09-25 18:32 ` BUFFER_SWITCH_EVENT Eli Zaretskii 2018-09-25 19:05 ` BUFFER_SWITCH_EVENT Eli Zaretskii 0 siblings, 2 replies; 42+ messages in thread From: Stefan Monnier @ 2018-09-25 18:14 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel >> >> We already look them up presumably in the right place. I don't >> >> understand why we'd need to look them up again after running >> >> a process filter. >> > Because a filter could have switched buffers, I presume. >> >> I don't follow: >> >> 1- we enter read-key-sequence >> 2- we read the set of keymaps >> 3- some process filter is executed, changing the current buffer >> 4- the set of keymaps that we need to use is still the same we computed >> at 2 and the keymaps themselves are also still the same >> >> What am I missing? > > You are asking the wrong guy, but I will try anyway: since the buffer > changed, we need to replay the key sequence using the keymaps local to > that buffer, not the ones we computed at 2. Right? I don't think so: we shouldn't use the keymaps in the buffer where the process filter ran but the keymaps in the buffer of the selected window (or the window into which the user pressed the mouse button). I suspect that the main original use for this special input event has been made redundant when we changed read-key-sequence to recompute the set of active keymaps when it receives the first event. I just changed my local Emacs by removing this special event (and related code, see patch below). I'll see if I notice any consequence. Stefan commit eace674910f89f2f2b685cf93c0c152460c11347 Author: Stefan Monnier <monnier@iro.umontreal.ca> Date: Tue Sep 25 12:11:00 2018 -0400 Get rid of BUFFER_SWITCH_EVENT diff --git a/src/keyboard.c b/src/keyboard.c index f62f93dc22..2ca09f394c 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -726,8 +726,9 @@ void force_auto_save_soon (void) { last_auto_save = - auto_save_interval - 1; - - record_asynch_buffer_change (); + /* FIXME: What does record_asynch_buffer_change have to do with forcing + an auto-save? */ + /* record_asynch_buffer_change (); */ } #endif \f @@ -2836,12 +2837,6 @@ read_char (int commandflag, Lisp_Object map, goto wrong_kboard; } - /* Buffer switch events are only for internal wakeups - so don't show them to the user. - Also, don't record a key if we already did. */ - if (BUFFERP (c)) - goto exit; - /* Process special events within read_char and loop around to read another event. */ save = Vquit_flag; @@ -3125,7 +3120,7 @@ read_char (int commandflag, Lisp_Object map, && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_click)) XSETCAR (help_form_saved_window_configs, Qnil); } - while (BUFFERP (c)); + while (false); /* Remove the help from the frame. */ unbind_to (count, Qnil); @@ -3135,7 +3130,7 @@ read_char (int commandflag, Lisp_Object map, cancel_echoing (); do c = read_char (0, Qnil, Qnil, 0, NULL); - while (BUFFERP (c)); + while (false); } } @@ -3375,8 +3370,7 @@ readable_events (int flags) if (event == kbd_buffer + KBD_BUFFER_SIZE) event = kbd_buffer; if (!((flags & READABLE_EVENTS_FILTER_EVENTS) - && (event->kind == FOCUS_IN_EVENT - || event->kind == BUFFER_SWITCH_EVENT)) + && event->kind == FOCUS_IN_EVENT) && !((flags & READABLE_EVENTS_IGNORE_SQUEEZABLES) && (event->kind == SCROLL_BAR_CLICK_EVENT || event->kind == HORIZONTAL_SCROLL_BAR_CLICK_EVENT) @@ -3538,14 +3532,6 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event, return; } } - /* Don't insert two BUFFER_SWITCH_EVENT's in a row. - Just ignore the second one. */ - else if (event->kind == BUFFER_SWITCH_EVENT - && kbd_fetch_ptr != kbd_store_ptr - && ((kbd_store_ptr == kbd_buffer - ? kbd_buffer + KBD_BUFFER_SIZE - 1 - : kbd_store_ptr - 1)->kind) == BUFFER_SWITCH_EVENT) - return; if (kbd_store_ptr - kbd_buffer == KBD_BUFFER_SIZE) kbd_store_ptr = kbd_buffer; @@ -3945,7 +3931,6 @@ kbd_buffer_get_event (KBOARD **kbp, #ifdef HAVE_XWIDGETS case XWIDGET_EVENT: #endif - case BUFFER_SWITCH_EVENT: case SAVE_SESSION_EVENT: case NO_EVENT: case HELP_EVENT: @@ -5348,14 +5333,6 @@ make_lispy_event (struct input_event *event) return list2 (Qmove_frame, list1 (event->frame_or_window)); #endif - case BUFFER_SWITCH_EVENT: - { - /* The value doesn't matter here; only the type is tested. */ - Lisp_Object obj; - XSETBUFFER (obj, current_buffer); - return obj; - } - /* Just discard these, by returning nil. With MULTI_KBOARD, these events are used as placeholders when we need to randomly delete events from the queue. @@ -6830,41 +6807,6 @@ get_input_pending (int flags) return input_pending; } -/* Put a BUFFER_SWITCH_EVENT in the buffer - so that read_key_sequence will notice the new current buffer. */ - -void -record_asynch_buffer_change (void) -{ - /* We don't need a buffer-switch event unless Emacs is waiting for input. - The purpose of the event is to make read_key_sequence look up the - keymaps again. If we aren't in read_key_sequence, we don't need one, - and the event could cause trouble by messing up (input-pending-p). - Note: Fwaiting_for_user_input_p always returns nil when async - subprocesses aren't supported. */ - if (!NILP (Fwaiting_for_user_input_p ())) - { - struct input_event event; - - EVENT_INIT (event); - event.kind = BUFFER_SWITCH_EVENT; - event.frame_or_window = Qnil; - event.arg = Qnil; - - /* Make sure no interrupt happens while storing the event. */ -#ifdef USABLE_SIGIO - if (interrupt_input) - kbd_buffer_store_event (&event); - else -#endif - { - stop_polling (); - kbd_buffer_store_event (&event); - start_polling (); - } - } -} - /* Read any terminal input already buffered up by the system into the kbd_buffer, but do not wait. @@ -8690,7 +8632,7 @@ read_char_minibuf_menu_prompt (int commandflag, kset_defining_kbd_macro (current_kboard, Qnil); do obj = read_char (commandflag, Qnil, Qt, 0, NULL); - while (BUFFERP (obj)); + while (false); kset_defining_kbd_macro (current_kboard, orig_defn_macro); if (!FIXNUMP (obj) || XFIXNUM (obj) == -2 @@ -9242,29 +9184,6 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt, break; } - /* If the current buffer has been changed from under us, the - keymap may have changed, so replay the sequence. */ - if (BUFFERP (key)) - { - timer_resume_idle (); - - mock_input = t; - /* Reset the current buffer from the selected window - in case something changed the former and not the latter. - This is to be more consistent with the behavior - of the command_loop_1. */ - if (fix_current_buffer) - { - if (! FRAME_LIVE_P (XFRAME (selected_frame))) - Fkill_emacs (Qnil); - if (XBUFFER (XWINDOW (selected_window)->contents) - != current_buffer) - Fset_buffer (XWINDOW (selected_window)->contents); - } - - goto replay_sequence; - } - /* If we have a quit that was typed in another frame, and quit_throw_to_read_char switched buffers, replay to get the right keymap. */ diff --git a/src/keyboard.h b/src/keyboard.h index ce4630b8a3..d4b5811298 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -446,7 +446,6 @@ extern void push_kboard (struct kboard *); extern void push_frame_kboard (struct frame *); extern void pop_kboard (void); extern void temporarily_switch_to_single_kboard (struct frame *); -extern void record_asynch_buffer_change (void); extern void input_poll_signal (int); extern void start_polling (void); extern void stop_polling (void); diff --git a/src/process.c b/src/process.c index d35ea84945..6d5d92560a 100644 --- a/src/process.c +++ b/src/process.c @@ -5150,14 +5150,6 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, timer_delay = timer_check (); - /* If a timer has run, this might have changed buffers - an alike. Make read_key_sequence aware of that. */ - if (timers_run != old_timers_run - && (old_buffer != current_buffer - || !EQ (old_window, selected_window)) - && waiting_for_user_input_p == -1) - record_asynch_buffer_change (); - if (timers_run != old_timers_run && do_display) /* We must retry, since a timer may have requeued itself and that could alter the time_delay. */ @@ -5527,14 +5519,6 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, leave = true; } - /* If a timer has run, this might have changed buffers - an alike. Make read_key_sequence aware of that. */ - if (timers_run != old_timers_run - && waiting_for_user_input_p == -1 - && (old_buffer != current_buffer - || !EQ (old_window, selected_window))) - record_asynch_buffer_change (); - if (leave) break; } @@ -6024,18 +6008,6 @@ read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars, /* Restore waiting_for_user_input_p as it was when we were called, in case the filter clobbered it. */ waiting_for_user_input_p = waiting; - -#if 0 /* Call record_asynch_buffer_change unconditionally, - because we might have changed minor modes or other things - that affect key bindings. */ - if (! EQ (Fcurrent_buffer (), obuffer) - || ! EQ (current_buffer->keymap, okeymap)) -#endif - /* But do it only if the caller is actually going to read events. - Otherwise there's no need to make him wake up, and it could - cause trouble (for example it would make sit_for return). */ - if (waiting_for_user_input_p == -1) - record_asynch_buffer_change (); } DEFUN ("internal-default-process-filter", Finternal_default_process_filter, @@ -7188,16 +7160,6 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason) when we were called, in case the filter clobbered it. */ waiting_for_user_input_p = waiting; -#if 0 - if (! EQ (Fcurrent_buffer (), obuffer) - || ! EQ (current_buffer->keymap, okeymap)) -#endif - /* But do it only if the caller is actually going to read events. - Otherwise there's no need to make him wake up, and it could - cause trouble (for example it would make sit_for return). */ - if (waiting_for_user_input_p == -1) - record_asynch_buffer_change (); - unbind_to (count, Qnil); } diff --git a/src/termhooks.h b/src/termhooks.h index b90ebc66e4..3cf5fb036e 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -160,7 +160,6 @@ enum event_kind SELECTION_REQUEST_EVENT, /* Another X client wants a selection from us. See `struct selection_input_event'. */ SELECTION_CLEAR_EVENT, /* Another X client cleared our selection. */ - BUFFER_SWITCH_EVENT, /* A process filter has switched buffers. */ DELETE_WINDOW_EVENT, /* An X client said "delete this window". */ #ifdef HAVE_NTGUI END_SESSION_EVENT, /* The user is logging out or shutting down. */ diff --git a/src/w32term.c b/src/w32term.c index 8d189ae32c..259361f738 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -4718,8 +4718,10 @@ w32_read_socket (struct terminal *terminal, } else if (!NILP (Vframe_list) && !NILP (XCDR (Vframe_list))) /* Force a redisplay sooner or later to update the - frame titles in case this is the second frame. */ - record_asynch_buffer_change (); + frame titles in case this is the second frame. + FIXME: What does record_asynch_buffer_change have + to do with forcing a redisplay? */ + /* record_asynch_buffer_change () */; } else { @@ -5277,8 +5279,10 @@ w32_read_socket (struct terminal *terminal, && ! NILP (XCDR (Vframe_list))) /* Force a redisplay sooner or later to update the frame titles - in case this is the second frame. */ - record_asynch_buffer_change (); + in case this is the second frame. + FIXME: What does record_asynch_buffer_change have + to do with forcing a redisplay? */ + /* record_asynch_buffer_change () */; /* Windows can send us a SIZE_MAXIMIZED message even when fullscreen is fullboth. The following is a @@ -5330,8 +5334,10 @@ w32_read_socket (struct terminal *terminal, && ! NILP (XCDR (Vframe_list))) /* Force a redisplay sooner or later to update the frame titles - in case this is the second frame. */ - record_asynch_buffer_change (); + in case this is the second frame. + FIXME: What does record_asynch_buffer_change have + to do with forcing a redisplay? */ + /* record_asynch_buffer_change () */; } if (EQ (get_frame_param (f, Qfullscreen), Qmaximized)) @@ -5623,8 +5629,10 @@ w32_read_socket (struct terminal *terminal, DebPrint (("obscured frame %p (%s) found to be visible\n", f, SDATA (f->name))); - /* Force a redisplay sooner or later. */ - record_asynch_buffer_change (); + /* Force a redisplay sooner or later. + FIXME: What does record_asynch_buffer_change have + to do with forcing a redisplay? */ + /* record_asynch_buffer_change () */; } } } diff --git a/src/xterm.c b/src/xterm.c index 08d40ac109..8f788626b6 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -8192,8 +8192,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, } else if (! NILP (Vframe_list) && ! NILP (XCDR (Vframe_list))) /* Force a redisplay sooner or later to update the - frame titles in case this is the second frame. */ - record_asynch_buffer_change (); + frame titles in case this is the second frame. + FIXME: What does record_asynch_buffer_change have + to do with forcing a redisplay? */ + /* record_asynch_buffer_change () */; } goto OTHER; ^ permalink raw reply related [flat|nested] 42+ messages in thread
* Re: BUFFER_SWITCH_EVENT 2018-09-25 18:14 ` BUFFER_SWITCH_EVENT Stefan Monnier @ 2018-09-25 18:32 ` Eli Zaretskii 2018-09-25 19:05 ` BUFFER_SWITCH_EVENT Eli Zaretskii 1 sibling, 0 replies; 42+ messages in thread From: Eli Zaretskii @ 2018-09-25 18:32 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Date: Tue, 25 Sep 2018 14:14:26 -0400 > Cc: emacs-devel@gnu.org > > I suspect that the main original use for this special input event has > been made redundant when we changed read-key-sequence to recompute the > set of active keymaps when it receives the first event. Like I said: you are asking the wrong guy. You should be asking yourself, since no one did more changes in this area recently than you did. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: BUFFER_SWITCH_EVENT 2018-09-25 18:14 ` BUFFER_SWITCH_EVENT Stefan Monnier 2018-09-25 18:32 ` BUFFER_SWITCH_EVENT Eli Zaretskii @ 2018-09-25 19:05 ` Eli Zaretskii 2018-09-25 21:50 ` BUFFER_SWITCH_EVENT Stefan Monnier 1 sibling, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-09-25 19:05 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Date: Tue, 25 Sep 2018 14:14:26 -0400 > Cc: emacs-devel@gnu.org > > - if (fix_current_buffer) > - { > - if (! FRAME_LIVE_P (XFRAME (selected_frame))) > - Fkill_emacs (Qnil); > - if (XBUFFER (XWINDOW (selected_window)->contents) > - != current_buffer) > - Fset_buffer (XWINDOW (selected_window)->contents); > - } This part restores the current buffer from the selected-window's buffer. With it deleted, what if a process filter or a timer switches buffers while we are processing a key sequence? ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: BUFFER_SWITCH_EVENT 2018-09-25 19:05 ` BUFFER_SWITCH_EVENT Eli Zaretskii @ 2018-09-25 21:50 ` Stefan Monnier 2018-09-26 5:42 ` BUFFER_SWITCH_EVENT Eli Zaretskii 0 siblings, 1 reply; 42+ messages in thread From: Stefan Monnier @ 2018-09-25 21:50 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel >> - if (fix_current_buffer) >> - { >> - if (! FRAME_LIVE_P (XFRAME (selected_frame))) >> - Fkill_emacs (Qnil); >> - if (XBUFFER (XWINDOW (selected_window)->contents) >> - != current_buffer) >> - Fset_buffer (XWINDOW (selected_window)->contents); >> - } > This part restores the current buffer from the selected-window's > buffer. With it deleted, what if a process filter or a timer switches > buffers while we are processing a key sequence? Indeed, what if? This is read_key_sequence: its return value should depend on where the keys&buttons are pressed rather than the context in which the function is called, so it should presumably not be affected by current-buffer as long as it uses the right set of active keymaps. I suspect we do need some `Fset_buffer (XWINDOW (selected_window)->contents)` maybe inside active_maps or right after `replay_sequence:` but I haven't managed to trigger problems linked to that yet. The `starting_buffer` business also looks a bit fishy. Stefan ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: BUFFER_SWITCH_EVENT 2018-09-25 21:50 ` BUFFER_SWITCH_EVENT Stefan Monnier @ 2018-09-26 5:42 ` Eli Zaretskii 2018-09-26 12:27 ` BUFFER_SWITCH_EVENT Stefan Monnier 0 siblings, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-09-26 5:42 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: emacs-devel@gnu.org > Date: Tue, 25 Sep 2018 17:50:21 -0400 > > >> - if (fix_current_buffer) > >> - { > >> - if (! FRAME_LIVE_P (XFRAME (selected_frame))) > >> - Fkill_emacs (Qnil); > >> - if (XBUFFER (XWINDOW (selected_window)->contents) > >> - != current_buffer) > >> - Fset_buffer (XWINDOW (selected_window)->contents); > >> - } > > This part restores the current buffer from the selected-window's > > buffer. With it deleted, what if a process filter or a timer switches > > buffers while we are processing a key sequence? > > Indeed, what if? > > This is read_key_sequence: its return value should depend on where the > keys&buttons are pressed No, I meant the effect of the above on the global state, not on what read_key_sequence returns. keyboard.c code is not only about reading input, it is part of the main loop, so it affects the global state due to changes done by timers, process filters, etc. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: BUFFER_SWITCH_EVENT 2018-09-26 5:42 ` BUFFER_SWITCH_EVENT Eli Zaretskii @ 2018-09-26 12:27 ` Stefan Monnier 0 siblings, 0 replies; 42+ messages in thread From: Stefan Monnier @ 2018-09-26 12:27 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel >> This is read_key_sequence: its return value should depend on where the >> keys&buttons are pressed > > No, I meant the effect of the above on the global state, not on what > read_key_sequence returns. keyboard.c code is not only about reading > input, it is part of the main loop, so it affects the global state due > to changes done by timers, process filters, etc. I see. I don't see why it should be read_key_sequence's responsability to "fix" those issues (and honestly, I don't see exactly what bad consequences it could have anyway. AFAIK the command loop will/should select the selected-window's buffer before running the next command). If we're preoccupied from such async changes to current-buffer, I think we should save&restore the current buffer around the code which runs process filters and timers (and indeed, if we treated them as Elisp threads, that's the behavior we'd get). Stefan ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-24 16:14 ` Eli Zaretskii 2018-09-24 16:40 ` Stefan Monnier 2018-09-24 17:39 ` Michael Heerdegen @ 2018-09-24 21:23 ` Andreas Schwab 2018-09-25 10:36 ` Michael Heerdegen 2 siblings, 1 reply; 42+ messages in thread From: Andreas Schwab @ 2018-09-24 21:23 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Michael Heerdegen, emacs-devel On Sep 24 2018, Eli Zaretskii <eliz@gnu.org> wrote: > Is it while-no-input that returns immediately, or is it sit-for? while-no-input always returns immediately after the body has finished executing. Andreas. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different." ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-24 21:23 ` while-no-input interrupted by *shell* Andreas Schwab @ 2018-09-25 10:36 ` Michael Heerdegen 0 siblings, 0 replies; 42+ messages in thread From: Michael Heerdegen @ 2018-09-25 10:36 UTC (permalink / raw) To: Andreas Schwab; +Cc: Eli Zaretskii, emacs-devel Andreas Schwab <schwab@linux-m68k.org> writes: > > Is it while-no-input that returns immediately, or is it sit-for? > > while-no-input always returns immediately after the body has finished > executing. True, but it doesn't seem that this is what is happening. Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input interrupted by *shell* 2018-09-24 15:24 while-no-input interrupted by *shell* Michael Heerdegen 2018-09-24 16:14 ` Eli Zaretskii @ 2018-09-24 16:19 ` Stefan Monnier 2018-09-25 17:47 ` while-no-input and pending input (was: while-no-input interrupted by *shell*) Michael Heerdegen 2 siblings, 0 replies; 42+ messages in thread From: Stefan Monnier @ 2018-09-24 16:19 UTC (permalink / raw) To: emacs-devel > I found another annoyance with `while-no-input': If you have a *shell* > buffer producing output - for example run something like ls -R in > *shell* - then `while-no-input' is obviously interrupted by what's going > on there. For example I object to the "obviously" above. > Is this expected, No, it's a bug. > and is there a way to avoid this behavior? I think the first step is to figure out what triggers this bug. E.g. maybe run your Emacs under a debugger, place a breakpoint on Fthrow (Vthrow_on_input, Qt); in process_quit_flag (in src/eval.c), then reproduce the problem. Hopefully you'll be able to get a backtrace that gives a good hint at why the while-no-input is interrupted. Stefan ^ permalink raw reply [flat|nested] 42+ messages in thread
* while-no-input and pending input (was: while-no-input interrupted by *shell*) 2018-09-24 15:24 while-no-input interrupted by *shell* Michael Heerdegen 2018-09-24 16:14 ` Eli Zaretskii 2018-09-24 16:19 ` Stefan Monnier @ 2018-09-25 17:47 ` Michael Heerdegen 2018-09-25 17:53 ` Drew Adams 2018-09-26 14:18 ` while-no-input and pending input (was: while-no-input interrupted by *shell*) Eli Zaretskii 2 siblings, 2 replies; 42+ messages in thread From: Michael Heerdegen @ 2018-09-25 17:47 UTC (permalink / raw) To: Emacs Development Hello again, I ran into other trouble with `while-no-input': A command I use - it calls w-n-i to generate feedback for the echo area unless the user hits a key - sometimes needs to select a different frame. AFAIK this generates an event and w-n-i then does nothing because of its implicit `input-pending-p' test. Using a modified version of w-n-i with the input-pending-p test removed solves the problem, but that's not good because (1) I have to duplicate the definition of w-n-i in my code (it's what Helm does btw.) and (2) hmm, can doing this have downsides? What could I else do in this situation to prevent the frame switch or whatever event to be misinterpreted as user input? Could/should w-n-i generally ignore events in `while-no-input-ignore-events' - I mean, also the input-pending-p part? Thanks, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* RE: while-no-input and pending input (was: while-no-input interrupted by *shell*) 2018-09-25 17:47 ` while-no-input and pending input (was: while-no-input interrupted by *shell*) Michael Heerdegen @ 2018-09-25 17:53 ` Drew Adams 2018-09-26 12:50 ` while-no-input and pending input Michael Heerdegen 2018-09-26 14:18 ` while-no-input and pending input (was: while-no-input interrupted by *shell*) Eli Zaretskii 1 sibling, 1 reply; 42+ messages in thread From: Drew Adams @ 2018-09-25 17:53 UTC (permalink / raw) To: Michael Heerdegen, Emacs Development > I ran into other trouble with `while-no-input': A command I use - it > calls w-n-i to generate feedback for the echo area unless the user hits > a key - sometimes needs to select a different frame. AFAIK this > generates an event and w-n-i then does nothing because of its implicit > `input-pending-p' test. > > Using a modified version of w-n-i with the input-pending-p test removed > solves the problem, but that's not good because (1) I have to duplicate > the definition of w-n-i in my code (it's what Helm does btw.) and (2) > hmm, can doing this have downsides? > > What could I else do in this situation to prevent the frame switch or > whatever event to be misinterpreted as user input? Could/should w-n-i > generally ignore events in `while-no-input-ignore-events' - I mean, also > the input-pending-p part? Dunno whether this helps or whether it's a good idea, but this is what I do: (defun icicle-skip-this-command () "Prevent `handle-switch-frame' from being added to `this-command'." (interactive) (setq this-command last-command)) (defun icicle-handle-switch-frame (event) "Call `handle-switch-frame', but don't add it to `this-command'." (interactive "e") (handle-switch-frame event) (setq this-command last-command)) (define-key global-map [handle-switch-frame] 'icicle-skip-this-command) (define-key global-map [switch-frame] 'icicle-handle-switch-frame)) ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input and pending input 2018-09-25 17:53 ` Drew Adams @ 2018-09-26 12:50 ` Michael Heerdegen 0 siblings, 0 replies; 42+ messages in thread From: Michael Heerdegen @ 2018-09-26 12:50 UTC (permalink / raw) To: Drew Adams; +Cc: Emacs Development Drew Adams <drew.adams@oracle.com> writes: > Dunno whether this helps or whether it's a good idea, but this is what > I do: > > (defun icicle-skip-this-command () > "Prevent `handle-switch-frame' from being added to `this-command'." > (interactive) > (setq this-command last-command)) > > (defun icicle-handle-switch-frame (event) > "Call `handle-switch-frame', but don't add it to `this-command'." > (interactive "e") > (handle-switch-frame event) > (setq this-command last-command)) > > (define-key global-map [handle-switch-frame] 'icicle-skip-this-command) > (define-key global-map [switch-frame] 'icicle-handle-switch-frame)) Thanks for sharing. But it doesn't help in this case. The problem is that the event gets in the way, not how it is processed. Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input and pending input (was: while-no-input interrupted by *shell*) 2018-09-25 17:47 ` while-no-input and pending input (was: while-no-input interrupted by *shell*) Michael Heerdegen 2018-09-25 17:53 ` Drew Adams @ 2018-09-26 14:18 ` Eli Zaretskii 2018-09-26 17:57 ` while-no-input and pending input Michael Heerdegen 1 sibling, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-09-26 14:18 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Date: Tue, 25 Sep 2018 19:47:41 +0200 > > What could I else do in this situation to prevent the frame switch or > whatever event to be misinterpreted as user input? Could/should w-n-i > generally ignore events in `while-no-input-ignore-events' - I mean, also > the input-pending-p part? I don't see how this could be done: AFAIK, these events are not visible in Lisp, at least some of them. Why cannot you drain the event queue before calling while-no-input? ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input and pending input 2018-09-26 14:18 ` while-no-input and pending input (was: while-no-input interrupted by *shell*) Eli Zaretskii @ 2018-09-26 17:57 ` Michael Heerdegen 2018-09-26 19:06 ` Eli Zaretskii 0 siblings, 1 reply; 42+ messages in thread From: Michael Heerdegen @ 2018-09-26 17:57 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > I don't see how this could be done: AFAIK, these events are not > visible in Lisp, at least some of them. Ok. > Why cannot you drain the event queue before calling while-no-input? How can I do this? `discard-input' is probably not what I want. Or should I do something with `unread-command-events'? Thanks, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input and pending input 2018-09-26 17:57 ` while-no-input and pending input Michael Heerdegen @ 2018-09-26 19:06 ` Eli Zaretskii 2018-10-12 15:38 ` Michael Heerdegen 2019-02-17 23:44 ` Michael Heerdegen 0 siblings, 2 replies; 42+ messages in thread From: Eli Zaretskii @ 2018-09-26 19:06 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: emacs-devel@gnu.org > Date: Wed, 26 Sep 2018 19:57:42 +0200 > > > Why cannot you drain the event queue before calling while-no-input? > > How can I do this? Call read-event with a short (or zero?) timeout in a loop, until it returns nil? ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input and pending input 2018-09-26 19:06 ` Eli Zaretskii @ 2018-10-12 15:38 ` Michael Heerdegen 2018-10-12 15:44 ` Stefan Monnier 2019-02-17 23:44 ` Michael Heerdegen 1 sibling, 1 reply; 42+ messages in thread From: Michael Heerdegen @ 2018-10-12 15:38 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > > > Why cannot you drain the event queue before calling while-no-input? > > > > How can I do this? > > Call read-event with a short (or zero?) timeout in a loop, until it > returns nil? Thanks, I'll try that. And afterwards I should add the events back to `unread-command-events'? Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input and pending input 2018-10-12 15:38 ` Michael Heerdegen @ 2018-10-12 15:44 ` Stefan Monnier 0 siblings, 0 replies; 42+ messages in thread From: Stefan Monnier @ 2018-10-12 15:44 UTC (permalink / raw) To: emacs-devel >> > > Why cannot you drain the event queue before calling while-no-input? >> > How can I do this? >> Call read-event with a short (or zero?) timeout in a loop, until it >> returns nil? > Thanks, I'll try that. > And afterwards I should add the events back to `unread-command-events'? Note that doing read-events and then pushing them to unread-command-events can have undesired side-effects, so it's better not to do that if at all possible. > Could/should w-n-i generally ignore events in > `while-no-input-ignore-events' - I mean, also the > input-pending-p part? Yes, it should. Stefan ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input and pending input 2018-09-26 19:06 ` Eli Zaretskii 2018-10-12 15:38 ` Michael Heerdegen @ 2019-02-17 23:44 ` Michael Heerdegen 2019-02-18 17:08 ` Eli Zaretskii 1 sibling, 1 reply; 42+ messages in thread From: Michael Heerdegen @ 2019-02-17 23:44 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > Call read-event with a short (or zero?) timeout in a loop, until it > returns nil? I found something worse: in an emacs -nw, when I eval something like (while-no-input (sit-for 20)) an hit any key I get a Quit. Why is that? Thanks, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input and pending input 2019-02-17 23:44 ` Michael Heerdegen @ 2019-02-18 17:08 ` Eli Zaretskii 2019-02-18 19:08 ` Óscar Fuentes 2019-02-18 22:32 ` Michael Heerdegen 0 siblings, 2 replies; 42+ messages in thread From: Eli Zaretskii @ 2019-02-18 17:08 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: emacs-devel@gnu.org > Date: Mon, 18 Feb 2019 00:44:37 +0100 > > I found something worse: in an emacs -nw, when I eval something like > > (while-no-input (sit-for 20)) > > an hit any key I get a Quit. Why is that? Some kind of regression, looks like starting with Emacs 25.1. Please submit a bug report. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input and pending input 2019-02-18 17:08 ` Eli Zaretskii @ 2019-02-18 19:08 ` Óscar Fuentes 2019-02-18 19:23 ` Eli Zaretskii 2019-02-18 22:32 ` Michael Heerdegen 1 sibling, 1 reply; 42+ messages in thread From: Óscar Fuentes @ 2019-02-18 19:08 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Michael Heerdegen, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> I found something worse: in an emacs -nw, when I eval something like >> >> (while-no-input (sit-for 20)) >> >> an hit any key I get a Quit. Why is that? > > Some kind of regression, looks like starting with Emacs 25.1. Please > submit a bug report. Bug#31692 possibly relevant here. The problem was fixed (on master, AFAIK). I can't reproduce it with 27.0.50 -Q, with or without -nw. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input and pending input 2019-02-18 19:08 ` Óscar Fuentes @ 2019-02-18 19:23 ` Eli Zaretskii 0 siblings, 0 replies; 42+ messages in thread From: Eli Zaretskii @ 2019-02-18 19:23 UTC (permalink / raw) To: Óscar Fuentes; +Cc: michael_heerdegen, emacs-devel > From: Óscar Fuentes <ofv@wanadoo.es> > Cc: Michael Heerdegen <michael_heerdegen@web.de>, emacs-devel@gnu.org > Date: Mon, 18 Feb 2019 20:08:43 +0100 > > >> (while-no-input (sit-for 20)) > >> > >> an hit any key I get a Quit. Why is that? > > > > Some kind of regression, looks like starting with Emacs 25.1. Please > > submit a bug report. > > Bug#31692 possibly relevant here. The problem was fixed (on master, > AFAIK). I can't reproduce it with 27.0.50 -Q, with or without -nw. I still see this with today's master on GNU/Linux in the -nw session. So either the fix for bug#31692 has regressed, or this is something different. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: while-no-input and pending input 2019-02-18 17:08 ` Eli Zaretskii 2019-02-18 19:08 ` Óscar Fuentes @ 2019-02-18 22:32 ` Michael Heerdegen 1 sibling, 0 replies; 42+ messages in thread From: Michael Heerdegen @ 2019-02-18 22:32 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > Some kind of regression, looks like starting with Emacs 25.1. Please > submit a bug report. Done - bug#34535. Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
end of thread, other threads:[~2019-02-18 22:32 UTC | newest] Thread overview: 42+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-09-24 15:24 while-no-input interrupted by *shell* Michael Heerdegen 2018-09-24 16:14 ` Eli Zaretskii 2018-09-24 16:40 ` Stefan Monnier 2018-09-24 17:00 ` Eli Zaretskii 2018-09-24 18:35 ` Stefan Monnier 2018-09-24 18:48 ` Eli Zaretskii 2018-09-24 17:39 ` Michael Heerdegen 2018-09-24 18:00 ` Eli Zaretskii 2018-09-24 19:09 ` Michael Heerdegen 2018-09-24 19:06 ` Stefan Monnier 2018-09-25 13:09 ` Eli Zaretskii 2018-09-25 13:39 ` Michael Heerdegen 2018-09-25 14:14 ` Eli Zaretskii 2018-09-29 7:13 ` Eli Zaretskii 2018-09-25 15:25 ` BUFFER_SWITCH_EVENT (was: while-no-input interrupted by *shell*) Stefan Monnier 2018-09-25 16:01 ` Eli Zaretskii 2018-09-25 16:14 ` BUFFER_SWITCH_EVENT Stefan Monnier 2018-09-25 16:28 ` BUFFER_SWITCH_EVENT Eli Zaretskii 2018-09-25 17:19 ` BUFFER_SWITCH_EVENT Stefan Monnier 2018-09-25 17:28 ` BUFFER_SWITCH_EVENT Eli Zaretskii 2018-09-25 18:14 ` BUFFER_SWITCH_EVENT Stefan Monnier 2018-09-25 18:32 ` BUFFER_SWITCH_EVENT Eli Zaretskii 2018-09-25 19:05 ` BUFFER_SWITCH_EVENT Eli Zaretskii 2018-09-25 21:50 ` BUFFER_SWITCH_EVENT Stefan Monnier 2018-09-26 5:42 ` BUFFER_SWITCH_EVENT Eli Zaretskii 2018-09-26 12:27 ` BUFFER_SWITCH_EVENT Stefan Monnier 2018-09-24 21:23 ` while-no-input interrupted by *shell* Andreas Schwab 2018-09-25 10:36 ` Michael Heerdegen 2018-09-24 16:19 ` Stefan Monnier 2018-09-25 17:47 ` while-no-input and pending input (was: while-no-input interrupted by *shell*) Michael Heerdegen 2018-09-25 17:53 ` Drew Adams 2018-09-26 12:50 ` while-no-input and pending input Michael Heerdegen 2018-09-26 14:18 ` while-no-input and pending input (was: while-no-input interrupted by *shell*) Eli Zaretskii 2018-09-26 17:57 ` while-no-input and pending input Michael Heerdegen 2018-09-26 19:06 ` Eli Zaretskii 2018-10-12 15:38 ` Michael Heerdegen 2018-10-12 15:44 ` Stefan Monnier 2019-02-17 23:44 ` Michael Heerdegen 2019-02-18 17:08 ` Eli Zaretskii 2019-02-18 19:08 ` Óscar Fuentes 2019-02-18 19:23 ` Eli Zaretskii 2019-02-18 22:32 ` Michael Heerdegen
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).