'map-y-or-n-p' now uses the minibuffer to read a char (bug#79664)

* lisp/emacs-lisp/map-ynp.el (map-y-or-n-p): Use the 'read-key'
branch only when the variable 'y-or-n-p-use-read-key' is non-nil.
Add a new cond-branch to read from the minibuffer.
Add a special case when def is nil in a kmacro in batch mode (bug#67836).

* test/lisp/files-tests.el (files-tests--with-buffer-offer-save):
Let-bind 'y-or-n-p-use-read-key' to t.
This commit is contained in:
Juri Linkov 2025-11-01 20:27:45 +02:00
parent ab4a616b0b
commit 2447188a69
3 changed files with 61 additions and 6 deletions

View file

@ -282,6 +282,10 @@ is still waiting for input.
It still can use 'read-key' when the variable
'read-char-choice-use-read-key' is non-nil.
*** 'map-y-or-n-p' now uses the minibuffer to read a character.
It still can use 'read-key' when the variable
'y-or-n-p-use-read-key' is non-nil.
** Mouse
*** New mode 'mouse-shift-adjust-mode' extends selection with 'S-<mouse-1>'.

View file

@ -96,6 +96,11 @@ This function uses `query-replace-map' to define the standard responses,
but only some of the responses which `query-replace' understands
are meaningful here, as described above.
By default, this function uses the minibuffer to read the key
non-modally (see `read-from-minibuffer'). However, if
`y-or-n-p-use-read-key' is non-nil, the modal `read-key'
function is used instead.
The function's value is the number of actions taken."
(let* ((actions 0)
(msg (current-message))
@ -161,11 +166,13 @@ The function's value is the number of actions taken."
(cond ((stringp prompt)
;; Prompt the user about this object.
(setq quit-flag nil)
(if use-menus
(setq def (or (x-popup-dialog (or mouse-event use-menus)
(cons prompt map))
'quit))
;; Prompt in the echo area.
(cond
(use-menus
(setq def (or (x-popup-dialog (or mouse-event use-menus)
(cons prompt map))
'quit)))
(y-or-n-p-use-read-key
;; Prompt in the echo area using `read-key'.
(let ((cursor-in-echo-area (not no-cursor-in-echo-area)))
(message "%s" (substitute-command-keys
(format
@ -203,7 +210,48 @@ The function's value is the number of actions taken."
"[end-of-keyboard-macro]"
(single-key-description char))))))
(setq def (lookup-key map (vector char))))
(cond ((eq def 'exit)
(t
;; Read from the minibuffer.
(let* ((full-prompt
(substitute-command-keys
(format
(apply #'propertize
"%s(\\`y', \\`n', \\`!', \\`.', \\`q', %sor \\`%s') "
minibuffer-prompt-properties)
prompt user-keys (help-key))))
(remap (make-sparse-keymap))
(cmd-char
(lambda ()
(interactive)
(setq char last-command-event)
(exit-minibuffer)))
(cmd-help
(lambda ()
(interactive)
(message "%s" (substitute-command-keys
(format
"Type \\`%s' for help"
(help-key))))))
(this-command this-command)
(real-this-command real-this-command)
(enable-recursive-minibuffers t)
(overriding-text-conversion-style nil))
(set-keymap-parent remap minibuffer-local-map)
(define-key remap [remap self-insert-command] cmd-help)
(cl--map-keymap-recursively
(lambda (key _cmd)
(define-key remap key cmd-char))
map)
(if minibuffer-auto-raise
(raise-frame (window-frame (minibuffer-window))))
(when (fboundp 'set-text-conversion-style)
(set-text-conversion-style text-conversion-style))
(read-from-minibuffer
full-prompt nil remap nil
(or y-or-n-p-history-variable t))
(message "%s%s" full-prompt (single-key-description char)))
(setq def (lookup-key map (vector char)))))
(cond ((eq def 'exit)
(setq next (lambda () nil)))
((eq def 'act)
;; Act on the object.
@ -274,6 +322,8 @@ Type \\`SPC' or \\`y' to %s the current %s;
;; switch-frame event. Put it off until we're done.
(setq delayed-switch-frame char)
(funcall try-again))
((eq def nil) ;; Special case for bug#67836
(error "Can't use in a kmacro in batch mode"))
(t
;; Random char.
(message "%s" (substitute-command-keys

View file

@ -2059,6 +2059,7 @@ CALLERS-DIR specifies the value to let-bind
(let* ((dir (make-temp-file "testdir" 'dir))
(inhibit-message t)
(use-dialog-box nil)
(y-or-n-p-use-read-key t)
buffers)
(pcase-dolist (`(,bufsym ,offer-save) buffers-offer)
(let* ((buf (generate-new-buffer (symbol-name bufsym)))