Allow read-multiple-choice to do long-form answers
authorLars Ingebrigtsen <larsi@gnus.org>
Fri, 24 Jun 2022 09:00:06 +0000 (11:00 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Fri, 24 Jun 2022 09:04:51 +0000 (11:04 +0200)
* doc/lispref/commands.texi (Reading One Event): Document it.

* lisp/emacs-lisp/rmc.el (read-multiple-choice): Allow using
long-form answers instead of single character ones.
(read-multiple-choice--long-answers): New function.
(read-multiple-choice--short-answers): Refactored out from the
main function.

doc/lispref/commands.texi
etc/NEWS
lisp/emacs-lisp/rmc.el

index 0a82bba3bc7984960c276ee19e77a67be77c3757..6f022183336fcd4e3459ee3adcfd04c4e4f3f87d 100644 (file)
@@ -3198,7 +3198,7 @@ causes it to evaluate @code{help-form} and display the result.  It
 then continues to wait for a valid input character, or keyboard-quit.
 @end defun
 
-@defun read-multiple-choice prompt choices &optional help-string show-help
+@defun read-multiple-choice prompt choices &optional help-string show-help long-form
 Ask user a multiple choice question.  @var{prompt} should be a string
 that will be displayed as the prompt.
 
@@ -3217,6 +3217,11 @@ If optional argument @var{show-help} is non-@code{nil}, the help
 buffer will be displayed immediately, before any user input.  If it is
 a string, use it as the name of the help buffer.
 
+If optional argument @var{long-form} is non-@code{nil}, the user
+will have to type in long-form answers (using @code{completing-read})
+instead of hitting a single key.  The answers must be among the second
+elements of the values in the @var{choices} list.
+
 The return value is the matching value from @var{choices}.
 
 @lisp
index 7ef710927419f2155c1bbb497e8a59bf6361ddc7..3ed7aae220455d52e0a71e1d068e940903253fda 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2104,6 +2104,9 @@ patcomp.el, pc-mode.el, pc-select.el, s-region.el, and sregex.el.
 \f
 * Lisp Changes in Emacs 29.1
 
++++
+** 'read-multiple-choice' can now use long-form answers.
+
 +++
 ** 'read-regexp' now allows the user to indicate whether to use case folding.
 
index 195035e6be91d97f53b197358ba81d11f49f56d9..dae6590b9bc5ddf287367a7971ba9ac47eb996e1 100644 (file)
@@ -23,8 +23,6 @@
 
 ;;; Code:
 
-(require 'seq)
-
 (defun rmc--add-key-description (elem)
   (let* ((char (car elem))
          (name (cadr elem))
     buf))
 
 ;;;###autoload
-(defun read-multiple-choice (prompt choices &optional help-string show-help)
+(defun read-multiple-choice (prompt choices &optional help-string show-help
+                                    long-form)
   "Ask user to select an entry from CHOICES, promting with PROMPT.
 This function allows to ask the user a multiple-choice question.
 
@@ -163,12 +162,21 @@ dialogs.  Otherwise, the function will always use text-mode dialogs.
 
 The return value is the matching entry from the CHOICES list.
 
+If LONG-FORM, do a `completing-read' over the NAME elements in
+CHOICES instead.
+
 Usage example:
 
 \(read-multiple-choice \"Continue connecting?\"
                       \\='((?a \"always\")
                         (?s \"session only\")
                         (?n \"no\")))"
+  (if long-form
+      (read-multiple-choice--long-answers prompt choices)
+    (read-multiple-choice--short-answers
+     prompt choices help-string show-help)))
+
+(defun read-multiple-choice--short-answers (prompt choices help-string show-help)
   (let* ((prompt-choices
           (if show-help choices (append choices '((?? "?")))))
          (altered-names (mapcar #'rmc--add-key-description prompt-choices))
@@ -244,6 +252,17 @@ Usage example:
       (kill-buffer buf))
     (assq tchar choices)))
 
+(defun read-multiple-choice--long-answers (prompt choices)
+  (let ((answer
+         (completing-read
+          (concat prompt " ("
+                  (mapconcat #'identity (mapcar #'cadr choices) "/")
+                  ") ")
+          (mapcar #'cadr choices) nil t)))
+    (seq-find (lambda (elem)
+                (equal (cadr elem) answer))
+              choices)))
+
 (provide 'rmc)
 
 ;;; rmc.el ends here