Skip to content

Instantly share code, notes, and snippets.

@stathissideris
Created September 9, 2020 09:21

Revisions

  1. stathissideris created this gist Sep 9, 2020.
    35 changes: 35 additions & 0 deletions read-line-menu.clj
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,35 @@
    ;; 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)))))))