Files
clojure-tui/src/tui/simple.clj
2026-01-21 01:16:37 -05:00

69 lines
1.7 KiB
Clojure

(ns tui.simple
"Simplified TUI runtime - no core.async, works with Babashka.
Synchronous event loop, no timers/async commands."
(:require [tui.terminal :as term]
[tui.input :as input]
[tui.render :as render]
[tui.ansi :as ansi]))
;; === Commands ===
(def quit [:quit])
;; === Key Matching ===
(defn key=
"Check if message is a specific key."
[msg key-pattern]
(input/key-match? msg key-pattern))
(defn key-str
"Get string representation of key."
[msg]
(input/key->str msg))
;; === Simple Run Loop ===
(defn run
"Run a TUI application (synchronous, no async commands).
Options:
- :init - Initial model (required)
- :update - (fn [model msg] [new-model cmd]) (required)
- :view - (fn [model] hiccup) (required)
- :alt-screen - Use alternate screen buffer (default false)
Returns the final model."
[{:keys [init update view alt-screen]
:or {alt-screen false}}]
;; Setup terminal
(term/init-input!)
(term/raw-mode!)
(when alt-screen (term/alt-screen!))
(term/clear!)
(try
;; Initial render
(term/render! (render/render (view init)))
;; Main loop - simple synchronous
(loop [model init]
(if-let [key-msg (input/read-key)]
(let [[new-model cmd] (update model key-msg)]
;; Render
(term/render! (render/render (view new-model)))
;; Check for quit
(if (= cmd [:quit])
new-model
(recur new-model)))
(recur model)))
(finally
;; Cleanup
(when alt-screen (term/exit-alt-screen!))
(term/restore!)
(term/close-input!)
(println))))
;; Re-export render
(def render render/render)