init
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
(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)
|
||||
Reference in New Issue
Block a user