[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#8948: 24.0.50; y-or-n-p doesn't support scroll-o-w like yes-or-no-p
From: |
Deniz Dogan |
Subject: |
bug#8948: 24.0.50; y-or-n-p doesn't support scroll-o-w like yes-or-no-p |
Date: |
Fri, 01 Jul 2011 11:25:03 +0200 |
User-agent: |
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20110624 Thunderbird/5.0 |
On 2011-06-30 21:30, Deniz Dogan wrote:
On 2011-06-30 16:57, Thierry Volpiatto wrote:
Thierry Volpiatto<thierry.volpiatto@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)))
- bug#8948: 24.0.50; y-or-n-p doesn't support scroll-o-w like yes-or-no-p,
Deniz Dogan <=