Skip to content

Instantly share code, notes, and snippets.

@stathissideris
Created September 9, 2020 09:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stathissideris/2984f53c1938a9b6f8bf4c3e7c4623f2 to your computer and use it in GitHub Desktop.
Save stathissideris/2984f53c1938a9b6f8bf4c3e7c4623f2 to your computer and use it in GitHub Desktop.
Example of a tiny menu system using read-line in Clojure
;; Usage:
(menu {:prompt "Which database"
:options ["Localhost" "Remote" {:id "o" :text "Other"}]})
;; Implementation
(require '[clojure.string :as str])
(defn menu [{:keys [prompt options]}]
(let [options (map (fn [o idx]
(if (string? o)
{:id (str (inc idx)) :text o}
o)) options (range))
valid-options (set (map :id options))]
(loop []
(when prompt
(println)
(println prompt)
(println))
(doseq [{:keys [id text]} options]
(println (str " [" id "]") text))
(println)
(println "or press <enter> to cancel")
(let [in (str/trim (read-line))]
(cond (= in "")
:cancelled
(not (valid-options in))
(do
(println (format "\n-- Invalid option '%s'!" in))
(recur))
:else
(first (filter #(= in (:id %)) options)))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment