Handle help-form in y-or-n-p and use this in find-file-noselect (bug#5423)
* doc/lispref/help.texi (Help Functions): Mention help-form for read-char-from-minibuffer and y-or-n-p. * doc/lispref/minibuf.texi (Yes-or-No Queries): Mention help-form for y-or-n-p. (Multiple Queries): Mention help-form for read-char-from-minibuffer. * lisp/files.el (find-file-noselect): Let-bind multi-line help text to help-form for y-or-n-p. * lisp/subr.el (read-char-choice): Mention help-form in docstring. (read-char-from-minibuffer): Mention help-form in docstring. (y-or-n-p-map): Remove handling of 'help'. (y-or-n-p): Mention help-form in docstring. When help-form is non-nil: add help-char to 'prompt', and bind help-char to help-form-show in composed-keymap.
This commit is contained in:
parent
789ee3e1d5
commit
0a8cd01162
5 changed files with 86 additions and 40 deletions
|
@ -676,8 +676,9 @@ If this variable is non-@code{nil}, its value is a form to evaluate
|
|||
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
|
||||
|
|
|
@ -2109,6 +2109,11 @@ special responses @code{recenter}, @code{scroll-up},
|
|||
@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
|
||||
|
@ -2317,6 +2322,11 @@ character. Optionally, it ignores any input that is not a member of
|
|||
@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
|
||||
|
|
6
etc/NEWS
6
etc/NEWS
|
@ -1773,6 +1773,12 @@ ledit.el, lmenu.el, lucid.el and old-whitespace.el.
|
|||
|
||||
* 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
|
||||
|
|
|
@ -2310,53 +2310,52 @@ the various files."
|
|||
;; 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"
|
||||
|
|
46
lisp/subr.el
46
lisp/subr.el
|
@ -2606,7 +2606,11 @@ This function is used by the `interactive' code letter `n'."
|
|||
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*"))
|
||||
|
@ -2767,8 +2771,11 @@ Optional argument HISTORY, if non-nil, should be a symbol that
|
|||
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))
|
||||
|
@ -2825,7 +2832,7 @@ If the caller has set `help-form', there is no need to explicitly add
|
|||
|
||||
(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))
|
||||
|
||||
|
@ -2880,6 +2887,12 @@ Return t if answer is \"y\" and nil if it is \"n\".
|
|||
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.
|
||||
|
||||
|
@ -2902,7 +2915,13 @@ is nil and `use-dialog-box' is non-nil."
|
|||
(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))
|
||||
|
@ -2911,6 +2930,7 @@ is nil and `use-dialog-box' is non-nil."
|
|||
(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)
|
||||
|
@ -2923,10 +2943,20 @@ is nil and `use-dialog-box' is non-nil."
|
|||
(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)))
|
||||
|
|
Loading…
Add table
Reference in a new issue