whenever the character @code{help-char} is read. If evaluating the form
produces a string, that string is displayed.
-A command that calls @code{read-event}, @code{read-char-choice}, or
-@code{read-char} probably should bind @code{help-form} to a
+A command that calls @code{read-event}, @code{read-char-choice},
+@code{read-char}, @code{read-char-from-minibuffer}, or
+@code{y-or-n-p} probably should bind @code{help-form} to a
non-@code{nil} expression while it does input. (The time when you
should not do this is when @kbd{C-h} has some other meaning.)
Evaluating this expression should result in a string that explains
@kbd{C-v}, @kbd{M-v}, @kbd{C-M-v} and @kbd{C-M-S-v} in
@code{query-replace-map}), this function performs the specified window
recentering or scrolling operation, and poses the question again.
+
+If you bind @code{help-form} (@pxref{Help Functions}) to
+a non-@code{nil} value while calling @code{y-or-n-p}, then pressing
+@code{help-char} causes it to evaluate @code{help-form} and display
+the result. @code{help-char} is automatically added to @var{prompt}.
@end defun
@defun y-or-n-p-with-timeout prompt seconds default
@var{chars}, a list of accepted characters. The @var{history}
argument specifies the history list symbol to use; if it is omitted or
@code{nil}, this function doesn't use the history.
+
+If you bind @code{help-form} (@pxref{Help Functions}) to
+a non-@code{nil} value while calling @code{read-char-from-minibuffer},
+then pressing @code{help-char} causes it to evaluate @code{help-form}
+and display the result.
@end defun
@node Reading a Password
\f
* Lisp Changes in Emacs 28.1
++++
+** 'read-char-from-minibuffer' and 'y-or-n-p' support 'help-form'.
+If you bind 'help-form' to a non-nil value while calling these functions,
+then pressing 'C-h' (help-char) causes the function to evaluate 'help-form'
+and display the result.
+
+++
** 'set-window-configuration' now takes an optional 'dont-set-frame'
parameter which, when non-nil, instructs the function not to select
;; hexl-mode or image-mode.
(memq major-mode '(hexl-mode image-mode)))
(if (buffer-modified-p)
- (if (y-or-n-p
- (format
- (if rawfile
- "The file %s is already visited normally,
+ (if (let ((help-form
+ (format-message
+ (if rawfile "\
+The file %s is already visited normally,
and you have edited the buffer. Now you have asked to visit it literally,
meaning no coding system handling, format conversion, or local variables.
-Emacs can visit a file in only one way at a time.
-
-Do you want to save the file, and visit it literally instead? "
- "The file %s is already visited literally,
+Emacs can visit a file in only one way at a time."
+ "\
+The file %s is already visited literally,
meaning no coding system handling, format conversion, or local variables.
You have edited the buffer. Now you have asked to visit the file normally,
-but Emacs can visit a file in only one way at a time.
-
-Do you want to save the file, and visit it normally instead? ")
- (file-name-nondirectory filename)))
+but Emacs can visit a file in only one way at a time.")
+ (file-name-nondirectory filename))))
+ (y-or-n-p
+ (if rawfile "\
+Do you want to save the file, and visit it literally instead? " "\
+Do you want to save the file, and visit it normally instead? ")))
(progn
(save-buffer)
(find-file-noselect-1 buf filename nowarn
rawfile truename number))
(if (y-or-n-p
- (format
- (if rawfile
- "\
-Do you want to discard your changes, and visit the file literally now? "
- "\
-Do you want to discard your changes, and visit the file normally now? ")))
+ (if rawfile "\
+Do you want to discard your changes, and visit the file literally now? " "\
+Do you want to discard your changes, and visit the file normally now? "))
(find-file-noselect-1 buf filename nowarn
rawfile truename number)
(error (if rawfile "File already visited non-literally"
"File already visited literally"))))
- (if (y-or-n-p
- (format
- (if rawfile
- "The file %s is already visited normally.
+ (if (let ((help-form
+ (format-message
+ (if rawfile "\
+The file %s is already visited normally.
You have asked to visit it literally,
meaning no coding system decoding, format conversion, or local variables.
-But Emacs can visit a file in only one way at a time.
-
-Do you want to revisit the file literally now? "
- "The file %s is already visited literally,
+But Emacs can visit a file in only one way at a time."
+ "\
+The file %s is already visited literally,
meaning no coding system decoding, format conversion, or local variables.
You have asked to visit it normally,
-but Emacs can visit a file in only one way at a time.
-
-Do you want to revisit the file normally now? ")
- (file-name-nondirectory filename)))
+but Emacs can visit a file in only one way at a time.")
+ (file-name-nondirectory filename))))
+ (y-or-n-p
+ (if rawfile "\
+Do you want to revisit the file literally now? " "\
+Do you want to revisit the file normally now? ")))
(find-file-noselect-1 buf filename nowarn
rawfile truename number)
(error (if rawfile "File already visited non-literally"
Any input that is not one of CHARS is ignored.
If optional argument INHIBIT-KEYBOARD-QUIT is non-nil, ignore
-keyboard-quit events while waiting for a valid input."
+keyboard-quit events while waiting for a valid input.
+
+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."
(unless (consp chars)
(error "Called `read-char-choice' without valid char choices"))
(let (char done show-help (helpbuf " *Char Help*"))
specifies the history list variable to use for navigating in input
history using `M-p' and `M-n', with `RET' to select a character from
history.
-If the caller has set `help-form', there is no need to explicitly add
-`help-char' to chars. It's bound automatically to `help-form-show'."
+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.
+There is no need to explicitly add `help-char' to CHARS;
+`help-char' is bound automatically to `help-form-show'."
(let* ((empty-history '())
(map (if (consp chars)
(or (gethash (list help-form (cons help-char chars))
(define-key map [remap skip] 'y-or-n-p-insert-n)
- (dolist (symbol '(help backup undo undo-all edit edit-replacement
+ (dolist (symbol '(backup undo undo-all edit edit-replacement
delete-and-edit ignore self-insert-command))
(define-key map (vector 'remap symbol) 'y-or-n-p-insert-other))
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.
+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.
(concat prompt
(if (or (zerop l) (eq ?\s (aref prompt (1- l))))
"" " ")
- (if dialog "" "(y or n) "))))))
+ (if dialog ""
+ (if help-form
+ (format "(y, n or %s) "
+ (key-description
+ (vector help-char)))
+ "(y or n) "
+ )))))))
(cond
(noninteractive
(setq prompt (funcall padded prompt))
(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))))))))
((and (display-popup-menus-p)
(setq prompt (funcall padded prompt))
(let* ((empty-history '())
(enable-recursive-minibuffers t)
+ (msg help-form)
+ (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))
(str (read-from-minibuffer
- prompt nil
- (make-composed-keymap y-or-n-p-map query-replace-map)
- nil
+ prompt nil keymap nil
(or y-or-n-p-history-variable 'empty-history))))
(setq answer (if (member str '("y" "Y")) 'act 'skip)))))
(let ((ret (eq answer 'act)))