emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 0a8cd01: Handle help-form in y-or-n-p and use this in find-file-n


From: Juri Linkov
Subject: master 0a8cd01: Handle help-form in y-or-n-p and use this in find-file-noselect (bug#5423)
Date: Sat, 21 Nov 2020 14:50:47 -0500 (EST)

branch: master
commit 0a8cd0116204354e95fbb4ebde64c58123502aa2
Author: Juri Linkov <juri@linkov.net>
Commit: Juri Linkov <juri@linkov.net>

    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.
---
 doc/lispref/help.texi    |  5 ++--
 doc/lispref/minibuf.texi | 10 ++++++++
 etc/NEWS                 |  6 +++++
 lisp/files.el            | 59 ++++++++++++++++++++++++------------------------
 lisp/subr.el             | 46 ++++++++++++++++++++++++++++++-------
 5 files changed, 86 insertions(+), 40 deletions(-)

diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi
index 2fa54e3..90406df 100644
--- a/doc/lispref/help.texi
+++ b/doc/lispref/help.texi
@@ -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
diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi
index b6a3434..f1cfd29 100644
--- a/doc/lispref/minibuf.texi
+++ b/doc/lispref/minibuf.texi
@@ -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
diff --git a/etc/NEWS b/etc/NEWS
index 0cfca39..9361cff 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1774,6 +1774,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
 the frame recorded in the configuration.
diff --git a/lisp/files.el b/lisp/files.el
index 3565b7f..49c9e5d 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -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"
diff --git a/lisp/subr.el b/lisp/subr.el
index 6e9f66f..1fb0f9a 100644
--- a/lisp/subr.el
+++ b/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)))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]