Am playing with read-multiple-choice to set completion-styles. Originally had (nth 1 sentry) but with '(basic substring), it will only pick up substring. Thus I can instead call (setq completion-styles sentry).

I cannot understand the error when making a selection.

(error "Invalid completion style 111")

Am I doing this right? Can I improve on the read-multiple-choice part?

(defun sentry (sentry)
  "Sets minibuffer completion style."

   (let ( (stysq '((?o '(orderless) "orderless")
                   (?b '(basic substring) "substring")
                   (?p '(partial-completion) "partial")
                   (?f '(flex) "flex")
                   (?i '(initials) "initials"))) )
           (read-multiple-choice "Sentry: " stysq)))

  (setq completion-styles (nth 1 sentry)))
  • 1
    Welcome back Mr. volatile identity. I still would advise you to try to read the documentation more carefully, and also to read once or twice more at least the 'Lists' section of the elisp reference... Nov 13, 2022 at 19:45
  • The funny thing is the generic descriptions that give no real help. It seems to me that the writers go to great lengths not to write useful examples and to avoid them completely.
    – Dilna
    Nov 13, 2022 at 19:54
  • There is an example in the docstring of read-multiple-choice. We have told you multiple times already that interactive expects a list. Also, we have provided multiple examples of how to use pcase. When solving these problems, you should try to become creative with the options you know about. Try to find the essence of what you are trying to achieve with each step. Nov 13, 2022 at 20:01
  • Looks as if it would be better to use strings (?o "orderless" "Use orderless completion.").
    – Dilna
    Nov 13, 2022 at 20:11
  • Wouldn't the selection pass a list? You seem to suggest that I should call (list after the interactive clause. Would that not produce a list of lists?
    – Dilna
    Nov 13, 2022 at 20:13

1 Answer 1


Remember that interactive expects a list as its argument. You can first get the choice and then get the value in a list using alist-get as the elements of choices are lists (not cons). Finally, you can read the string in value using read:

(defun sentry (sentry)
  "Sets minibuffer completion style."
   (let ((choices '((?o "(orderless)")
                    (?b "(basic substring)")
                    (?p "(partial-completion)")
                    (?f "(flex)")
                    (?i "(initials)"))))

     (alist-get (car (read-multiple-choice "Sentry: " choices))
  (message "`completion-style' set to %s"
           (setq completion-styles (read sentry))))
  • You search for ?o to pick out the "(orderless)" entry. Thought to use cadr at first.
    – Dilna
    Nov 13, 2022 at 20:50
  • Indeed, I am using alist-get to get the value from an alist. I think you know alist-get already, so why use cadr? If you do not know alist-get... then again... read the Lists section of the elisp reference. Nov 13, 2022 at 20:54
  • I know it. Do people prefer that, rather than cadr?
    – Dilna
    Nov 13, 2022 at 21:01
  • I don't know. What do you prefer? Nov 13, 2022 at 21:10

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.