GNU bug report logs -
#8948
24.0.50; y-or-n-p doesn't support scroll-o-w like yes-or-no-p
Previous Next
Full log
Message #14 received at submit <at> debbugs.gnu.org (full text, mbox):
On 2011-06-30 21:30, Deniz Dogan wrote:
> On 2011-06-30 16:57, Thierry Volpiatto wrote:
>> Thierry Volpiatto<thierry.volpiatto <at> gmail.com> writes:
>>
>>> Hi,
>>> after discussion about bug#8927, i discover that
>>> from a yes-or-no-p i can scroll-other-window, but not from a
>>> y-or-n-p.
>>
>> This allow scrolling from a y-or-n-p:
>>
>>
>> #+BEGIN_SRC lisp
>> (defun y-or-n-p (prompt)
>> "Ask user a \"y or n\" question. Return t if answer is \"y\".
>> 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."
>> ;; ¡Beware! when I tried to edebug this code, Emacs got into a weird
>> state
>> ;; where all the keys were unbound (i.e. it somehow got triggered
>> ;; within read-key, apparently). I had to kill it.
>> (let ((answer 'recenter))
>> (if (and (display-popup-menus-p)
>> (listp last-nonmenu-event)
>> use-dialog-box)
>> (setq answer
>> (x-popup-dialog t `(,prompt ("yes" . act) ("No" . skip))))
>> (setq prompt (concat prompt
>> (if (eq ?\s (aref prompt (1- (length prompt))))
>> "" " ")
>> "(y or n) "))
>> (while
>> (let* ((key
>> (let ((cursor-in-echo-area t))
>> (when minibuffer-auto-raise
>> (raise-frame (window-frame (minibuffer-window))))
>> (read-key (propertize (if (or (eq answer 'recenter)
>> (eq com 'scroll-other-window)
>> (eq com 'scroll-other-window-down))
>> prompt
>> (concat "Please answer y or n. "
>> prompt))
>> 'face 'minibuffer-prompt)))))
>> (setq answer (lookup-key query-replace-map (vector key) t))
>> (setq com (lookup-key global-map (vector key) t))
>> (cond
>> ((eq com 'scroll-other-window)
>> (with-selected-window (minibuffer-window)
>> (scroll-other-window 1)) t)
>> ((eq com 'scroll-other-window-down)
>> (with-selected-window (minibuffer-window)
>> (scroll-other-window -1)) t)
>> ((memq answer '(skip act)) nil)
>> ((eq answer 'recenter) (recenter) t)
>> ((memq answer '(exit-prefix quit)) (signal 'quit nil) t)
>> (t t)))
>> (ding)
>> (discard-input)))
>> (let ((ret (eq answer 'act)))
>> (unless noninteractive
>> (message "%s %s" prompt (if ret "y" "n")))
>> ret)))
>>
>> #+END_SRC
>>
>
>
> I'm not so sure that's a suitable solution. What if someone wants yet
> another command to work in `y-or-n-p'?
>
Here is an alternative solution which utilizes the current global map if
the answer is not found in query-replace-map.
I'm not sure this is suitable either since there is no telling what kind
of interactive commands that can mess things up for the user.
=== modified file 'lisp/subr.el'
--- lisp/subr.el 2011-06-21 08:55:22 +0000
+++ lisp/subr.el 2011-07-01 09:23:35 +0000
@@ -2158,15 +2158,16 @@
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'.\)
+for more information. If the character is not found within that map, it
+looks in the current global map instead.\)
Under a windowing system a dialog box will be used if `last-nonmenu-event'
is nil and `use-dialog-box' is non-nil."
;; ¡Beware! when I tried to edebug this code, Emacs got into a weird
state
;; where all the keys were unbound (i.e. it somehow got triggered
;; within read-key, apparently). I had to kill it.
- (let ((answer 'recenter))
+ (let (answer
+ (valid-answer t))
(if (and (display-popup-menus-p)
(listp last-nonmenu-event)
use-dialog-box)
@@ -2181,7 +2182,7 @@
(let ((cursor-in-echo-area t))
(when minibuffer-auto-raise
(raise-frame (window-frame (minibuffer-window))))
- (read-key (propertize (if (eq answer 'recenter)
+ (read-key (propertize (if valid-answer
prompt
(concat "Please answer y
or n. "
prompt))
@@ -2189,9 +2190,14 @@
(setq answer (lookup-key query-replace-map (vector key) t))
(cond
((memq answer '(skip act)) nil)
- ((eq answer 'recenter) (recenter) t)
((memq answer '(exit-prefix quit)) (signal 'quit nil) t)
- (t t)))
+ (t (setq answer (lookup-key (current-global-map) (vector
key) t))
+ (if (not (commandp answer))
+ (progn
+ (setq valid-answer nil)
+ t)
+ (call-interactively answer)
+ (setq valid-answer t)))))
(ding)
(discard-input)))
(let ((ret (eq answer 'act)))
This bug report was last modified 12 years and 262 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.