Function: y-or-n-p
y-or-n-p is a byte-compiled function defined in subr.el.gz.
Signature
(y-or-n-p PROMPT)
Documentation
Ask user a "y or n" question.
Return t if answer is "y" and nil if it is "n".
PROMPT is the string to display to ask the question; y-or-n-p
adds "(y or n) " to it. If PROMPT is a non-empty string, and
it ends with a non-space character, a space character will be
appended to it.
If you bind the variable help-form to a non-nil value
while calling this function, then pressing help-char
causes it to evaluate help-form and display the result.
PROMPT is also updated to show help-char like "(y, n or C-h) ",
where help-char is automatically bound to help-form-show.
No confirmation of the answer is requested; a single character is enough. SPC also means yes, and DEL means no.
To be precise, this function translates user input into responses
by consulting 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,
scroll-up, scroll-down, and quit.
An act response means yes, and a skip response means no.
A quit response means to invoke abort-recursive-edit.
If the user enters recenter, scroll-up, or scroll-down
responses, perform the requested window recentering or scrolling
and ask again.
If dialog boxes are supported, this function will use a dialog box
if use-dialog-box is non-nil and the last input event was produced
by a mouse, or by some window-system gesture, or via a menu.
By default, this function uses the minibuffer to read the key.
If y-or-n-p-use-read-key is non-nil, read-key is used
instead (which means that the user can't change buffers (and the
like) while y-or-n-p is running).
Probably introduced at or before Emacs version 19.23.
Source Code
;; Defined in /usr/src/emacs/lisp/subr.el.gz
(defun y-or-n-p (prompt)
"Ask user a \"y or n\" question.
Return t if answer is \"y\" and nil if it is \"n\".
PROMPT is the string to display to ask the question; `y-or-n-p'
adds \"(y or n) \" to it. If PROMPT is a non-empty string, and
it ends with a non-space character, a space character will be
appended to it.
If you bind the variable `help-form' to a non-nil value
while calling this function, then pressing `help-char'
causes it to evaluate `help-form' and display the result.
PROMPT is also updated to show `help-char' like \"(y, n or C-h) \",
where `help-char' is automatically bound to `help-form-show'.
No confirmation of the answer is requested; a single character is
enough. SPC also means yes, and DEL means no.
To be precise, this function translates user input into responses
by consulting 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',
`scroll-up', `scroll-down', and `quit'.
An `act' response means yes, and a `skip' response means no.
A `quit' response means to invoke `abort-recursive-edit'.
If the user enters `recenter', `scroll-up', or `scroll-down'
responses, perform the requested window recentering or scrolling
and ask again.
If dialog boxes are supported, this function will use a dialog box
if `use-dialog-box' is non-nil and the last input event was produced
by a mouse, or by some window-system gesture, or via a menu.
By default, this function uses the minibuffer to read the key.
If `y-or-n-p-use-read-key' is non-nil, `read-key' is used
instead (which means that the user can't change buffers (and the
like) while `y-or-n-p' is running)."
(let ((answer 'recenter)
(padded (lambda (prompt &optional dialog)
(let ((l (length prompt)))
(concat prompt
(if (or (zerop l) (eq ?\s (aref prompt (1- l))))
"" " ")
(if dialog ""
;; Don't clobber caller's match data.
(save-match-data
(substitute-command-keys
(if help-form
(format "(\\`y', \\`n' or \\`%s') "
(key-description
(vector help-char)))
"(\\`y' or \\`n') "))))))))
;; Preserve the actual command that eventually called
;; `y-or-n-p' (otherwise `repeat' will be repeating
;; `exit-minibuffer').
(real-this-command real-this-command))
(cond
(noninteractive
(setq prompt (funcall padded prompt))
(let ((temp-prompt prompt))
(while (not (memq answer '(act skip)))
(let ((str (read-string temp-prompt)))
(cond ((member str '("y" "Y")) (setq answer 'act))
((member str '("n" "N")) (setq answer 'skip))
((and (member str '("h" "H")) help-form) (print help-form))
(t (setq temp-prompt (concat "Please answer y or n. "
prompt))))))))
((use-dialog-box-p)
(setq prompt (funcall padded prompt t)
answer (x-popup-dialog t `(,prompt ("Yes" . act) ("No" . skip)))))
(y-or-n-p-use-read-key
;; ¡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.
(setq prompt (funcall padded prompt))
(while
(let* ((scroll-actions '(recenter scroll-up scroll-down
scroll-other-window scroll-other-window-down))
(key
(let ((cursor-in-echo-area t))
(when minibuffer-auto-raise
(raise-frame (window-frame (minibuffer-window))))
(read-key (propertize (if (memq answer scroll-actions)
prompt
(concat "Please answer y or n. "
prompt))
'face 'minibuffer-prompt)))))
(setq answer (lookup-key query-replace-map (vector key) t))
(cond
((memq answer '(skip act)) nil)
((eq answer 'recenter)
(recenter) t)
((eq answer 'scroll-up)
(ignore-errors (scroll-up-command)) t)
((eq answer 'scroll-down)
(ignore-errors (scroll-down-command)) t)
((eq answer 'scroll-other-window)
(ignore-errors (scroll-other-window)) t)
((eq answer 'scroll-other-window-down)
(ignore-errors (scroll-other-window-down)) t)
((or (memq answer '(exit-prefix quit)) (eq key ?\e))
(signal 'quit nil) t)
(t t)))
(ding)
(discard-input)))
(t
(setq prompt (funcall padded prompt))
(let* ((enable-recursive-minibuffers t)
(msg help-form)
;; Disable text conversion so that real Y or N events are
;; sent.
(overriding-text-conversion-style nil)
(keymap (let ((map (make-composed-keymap
y-or-n-p-map query-replace-map)))
(when help-form
;; Create a new map before modifying
(setq map (copy-keymap map))
(define-key map (vector help-char)
(lambda ()
(interactive)
(let ((help-form msg)) ; lexically bound msg
(help-form-show)))))
map))
;; Protect this-command when called from pre-command-hook (bug#45029)
(this-command this-command)
(str (progn
;; If the minibuffer is already active, the
;; selected window might not change. Disable
;; text conversion by hand.
(when (fboundp 'set-text-conversion-style)
(set-text-conversion-style text-conversion-style))
(read-from-minibuffer
prompt nil keymap nil
(or y-or-n-p-history-variable t)))))
(setq answer (if (member str '("y" "Y")) 'act 'skip)))))
(let ((ret (eq answer 'act)))
(unless noninteractive
(message "%s%c" prompt (if ret ?y ?n)))
ret)))