[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#6758: 23.2; xterm.el: please provide an option to not discard input
From: |
Stefan Monnier |
Subject: |
bug#6758: 23.2; xterm.el: please provide an option to not discard input in terminal-init-xterm |
Date: |
Sat, 11 Sep 2010 16:59:29 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) |
> Any thoughts on this patch?
> I've found further problems with doing aynchronous terminal queries:
> minibuffer prompts get aborted by the xterm response. For example,
> when opening up a large file:
> 1) Emacs loads and sends "\e[>0c"
> 2) Emacs prints the "File x is large (123MB), really open? (y or n)" prompt
> 3) Xterm sends the "\e[>0;253;0c" response, aborting the prompt
You can try the patch below (may require manual application, it's made
against a non-vanilla tree) to see if it fixes your problem,
Stefan
=== modified file 'lisp/subr.el'
--- lisp/subr.el 2010-09-11 09:14:23 +0000
+++ lisp/subr.el 2010-09-11 14:57:41 +0000
@@ -3680,6 +3680,52 @@
buffer)
+(defun y-or-n-p (prompt)
+ "Ask user a \"y or n\" question. Return t if answer is \"y\".
+The argument PROMPT is the string to display to ask the question.
+It should end in a space; `y-or-n-p' adds `(y or n) ' to it.
+No confirmation of the answer is requested; a single character is enough.
+Also accepts Space to mean yes, or Delete to mean no. \(Actually, it uses
+the bindings in `query-replace-map'; see the documentation of that variable
+for more information. In this case, the useful bindings are `act', `skip',
+`recenter', and `quit'.\)
+
+Under a windowing system a dialog box will be used if `last-nonmenu-event'
+is nil and `use-dialog-box' is non-nil."
+ (let ((answer 'none)
+ (xprompt (setq prompt (propertize (concat prompt "(y or n) ")
+ 'face 'minibuffer-prompt))))
+ (if (and (display-popup-menus-p)
+ (listp last-nonmenu-event)
+ use-dialog-box)
+ (progn
+ (setq answer
+ (x-popup-dialog t `(,prompt ("yes" . t) ("No" . nil)))))
+ (while
+ (progn
+ (when minibuffer-auto-raise
+ (raise-frame (window-frame (minibuffer-window))))
+ (let* ((key
+ (let ((cursor-in-echo-area t))
+ (read-key xprompt))))
+ (setq answer (lookup-key query-replace-map (vector key) t))
+ (case answer
+ ((skip act) nil)
+ (recenter (recenter) t)
+ ((exit-prefix quit) (signal 'quit nil) t)
+ (t t))))
+ (ding)
+ (discard-input)
+ (setq xprompt
+ (if (eq answer 'recenter) prompt
+ (propertize (concat "Please answer y or n. " prompt)
+ 'face 'minibuffer-prompt))))
+
+ (let ((ret (eq answer 'act)))
+ (unless noninteractive
+ (message "%s %s" prompt (if ret "y" "n")))
+ ret))))
+
;; (defun get-doc-string (pos &optional unibyte definition)
;; (let ((file (or (car-safe pos) internal-doc-file-name))
;; (position (or (cdr-safe pos) pos))
=== modified file 'src/fileio.c'
--- src/fileio.c 2010-08-10 10:46:59 +0000
+++ src/fileio.c 2010-09-11 14:22:33 +0000
@@ -1842,7 +1842,7 @@
tem = format2 ("File %s already exists; %s anyway? ",
absname, build_string (querystring));
if (quick)
- tem = Fy_or_n_p (tem);
+ tem = call1 (intern ("y-or-n-p"), tem);
else
tem = do_yes_or_no_p (tem);
UNGCPRO;
=== modified file 'src/fns.c'
--- src/fns.c 2010-08-14 22:35:37 +0000
+++ src/fns.c 2010-09-11 14:10:27 +0000
@@ -2437,146 +2437,6 @@
return sequence;
}
-/* Anything that calls this function must protect from GC! */
-
-DEFUN ("y-or-n-p", Fy_or_n_p, Sy_or_n_p, 1, 1, 0,
- doc: /* Ask user a "y or n" question. Return t if answer is "y".
-Takes one argument, which is the string to display to ask the question.
-It should end in a space; `y-or-n-p' adds `(y or n) ' to it.
-No confirmation of the answer is requested; a single character is enough.
-Also accepts Space to mean yes, or Delete to mean no. \(Actually, it uses
-the bindings in `query-replace-map'; see the documentation of that variable
-for more information. In this case, the useful bindings are `act', `skip',
-`recenter', and `quit'.\)
-
-Under a windowing system a dialog box will be used if `last-nonmenu-event'
-is nil and `use-dialog-box' is non-nil. */)
- (Lisp_Object prompt)
-{
- register Lisp_Object obj, key, def, map;
- register int answer;
- Lisp_Object xprompt;
- Lisp_Object args[2];
- struct gcpro gcpro1, gcpro2;
- int count = SPECPDL_INDEX ();
-
- specbind (Qcursor_in_echo_area, Qt);
-
- map = Fsymbol_value (intern ("query-replace-map"));
-
- CHECK_STRING (prompt);
- xprompt = prompt;
- GCPRO2 (prompt, xprompt);
-
-#ifdef HAVE_WINDOW_SYSTEM
- if (display_hourglass_p)
- cancel_hourglass ();
-#endif
-
- while (1)
- {
-
-#ifdef HAVE_MENUS
- if (FRAME_WINDOW_P (SELECTED_FRAME ())
- && (NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
- && use_dialog_box
- && have_menus_p ())
- {
- Lisp_Object pane, menu;
- redisplay_preserve_echo_area (3);
- pane = Fcons (Fcons (build_string ("Yes"), Qt),
- Fcons (Fcons (build_string ("No"), Qnil),
- Qnil));
- menu = Fcons (prompt, pane);
- obj = Fx_popup_dialog (Qt, menu, Qnil);
- answer = !NILP (obj);
- break;
- }
-#endif /* HAVE_MENUS */
- cursor_in_echo_area = 1;
- choose_minibuf_frame ();
-
- {
- Lisp_Object pargs[3];
-
- /* Colorize prompt according to `minibuffer-prompt' face. */
- pargs[0] = build_string ("%s(y or n) ");
- pargs[1] = intern ("face");
- pargs[2] = intern ("minibuffer-prompt");
- args[0] = Fpropertize (3, pargs);
- args[1] = xprompt;
- Fmessage (2, args);
- }
-
- if (minibuffer_auto_raise)
- {
- Lisp_Object mini_frame;
-
- mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window));
-
- Fraise_frame (mini_frame);
- }
-
- temporarily_switch_to_single_kboard (SELECTED_FRAME ());
- obj = read_filtered_event (1, 0, 0, 0, Qnil);
- cursor_in_echo_area = 0;
- /* If we need to quit, quit with cursor_in_echo_area = 0. */
- QUIT;
-
- key = Fmake_vector (make_number (1), obj);
- def = Flookup_key (map, key, Qt);
-
- if (EQ (def, intern ("skip")))
- {
- answer = 0;
- break;
- }
- else if (EQ (def, intern ("act")))
- {
- answer = 1;
- break;
- }
- else if (EQ (def, intern ("recenter")))
- {
- Frecenter (Qnil);
- xprompt = prompt;
- continue;
- }
- else if (EQ (def, intern ("quit")))
- Vquit_flag = Qt;
- /* We want to exit this command for exit-prefix,
- and this is the only way to do it. */
- else if (EQ (def, intern ("exit-prefix")))
- Vquit_flag = Qt;
-
- QUIT;
-
- /* If we don't clear this, then the next call to read_char will
- return quit_char again, and we'll enter an infinite loop. */
- Vquit_flag = Qnil;
-
- Fding (Qnil);
- Fdiscard_input ();
- if (EQ (xprompt, prompt))
- {
- args[0] = build_string ("Please answer y or n. ");
- args[1] = prompt;
- xprompt = Fconcat (2, args);
- }
- }
- UNGCPRO;
-
- if (! noninteractive)
- {
- cursor_in_echo_area = -1;
- message_with_string (answer ? "%s(y or n) y" : "%s(y or n) n",
- xprompt, 0);
- }
-
- unbind_to (count, Qnil);
- return answer ? Qt : Qnil;
-}
-
/* This is how C code calls `yes-or-no-p' and allows the user
to redefined it.
@@ -5057,7 +4917,6 @@
defsubr (&Smapcar);
defsubr (&Smapc);
defsubr (&Smapconcat);
- defsubr (&Sy_or_n_p);
defsubr (&Syes_or_no_p);
defsubr (&Sload_average);
defsubr (&Sfeaturep);
=== modified file 'src/lisp.h'
--- src/lisp.h 2010-09-10 23:24:48 +0000
+++ src/lisp.h 2010-09-11 14:09:41 +0000
@@ -2586,7 +2586,6 @@
EXFUN (Fnconc, MANY);
EXFUN (Fmapcar, 2);
EXFUN (Fmapconcat, 3);
-EXFUN (Fy_or_n_p, 1);
extern Lisp_Object do_yes_or_no_p (Lisp_Object);
EXFUN (Frequire, 3);
EXFUN (Fprovide, 2);