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

  • This looks like a dup. Perhaps someone can locate the duplicate.
    – Drew
    Apr 20, 2017 at 14:25

2 Answers 2


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."
  (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)))))
  • Awesome! This is exactly what I wanted to get
    – Valeriy
    Apr 20, 2017 at 20:16
(defun foo (choice)
   (list (completing-read "Choose: "
                          '(("1" . "Cow") ("2" . "Rabbit") ("3" . "Dog")) nil t)))
  (message "You chose `%s'" choice)

Or if you want to let the input be the first letter (or another prefix):

(defun foo (choice)
   (let ((completion-ignore-case  t))
     (list (completing-read "Choose: " '("Cow" "Rabbit" "Dog") nil t))))
  (message "You chose `%s'" choice)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.