Subject: Re: bug#8948: 24.0.50; y-or-n-p doesn't support scroll-o-w like yes-or-no-p

From: Deniz Dogan <[email-masked]>
Date: Thu, 30 Jun 2011 21:30:24 +0200

On 2011-06-30 16:57, Thierry Volpiatto wrote:
> Thierry Volpiatto<[email-masked]>  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'?

Deniz