How to write a function in Emacs Lisp that interactively would give the opportunity to choose one of the options?
Choose your animal: Cow Rabbit Dog
You have to press 1
to select Cow
, 2
to select Rabbit
and 3
to select Dog
How to write a function in Emacs Lisp that interactively would give the opportunity to choose one of the options?
Choose your animal: Cow Rabbit Dog
You have to press 1
to select Cow
, 2
to select Rabbit
and 3
to select Dog
The function you are looking for is read-char-choice
.
I cite the corresponding documentation:
(read-char-choice PROMPT CHARS &optional INHIBIT-KEYBOARD-QUIT)
Read and return one of CHARS, prompting for PROMPT. 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.
A usage example:
(defvar valeriy-alist '((?1 "Cow" (lambda () (message "I am a cow") 'cow))
(?2 "Rabbit" (lambda () (message "I am a lion") 'lion))
(?3 "Dog" (lambda () (message "I am a wolf") 'wolf)))
"List that associates number letters to descriptions and actions.")
(defun valeriy-choose ()
"Lets the user choose the animal and takes the corresponding action.
Returns whatever the action returns."
(interactive)
(let ((choice (read-char-choice (mapconcat (lambda (item) (format "%c: %s" (car item) (cadr item))) valeriy-alist "; ")
(mapcar #'car valeriy-alist))))
(funcall (nth 2 (assoc choice valeriy-alist)))))
(defun foo (choice)
"..."
(interactive
(list (completing-read "Choose: "
'(("1" . "Cow") ("2" . "Rabbit") ("3" . "Dog")) nil t)))
(message "You chose `%s'" choice)
choice)
Or if you want to let the input be the first letter (or another prefix):
(defun foo (choice)
"..."
(interactive
(let ((completion-ignore-case t))
(list (completing-read "Choose: " '("Cow" "Rabbit" "Dog") nil t))))
(message "You chose `%s'" choice)
choice)