Includes getting started guide, hiccup views reference, full API documentation, and annotated example walkthroughs with ASCII output examples. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
14 KiB
API Reference
Complete API documentation for Clojure TUI.
Table of Contents
- tui.core - Full async runtime
- tui.simple - Sync runtime (Babashka)
- tui.render - Hiccup rendering
- tui.input - Key input parsing
- tui.terminal - Terminal control
- tui.ansi - ANSI escape codes
tui.core
Full-featured async runtime using core.async. Use this when you need timers, async commands, or background operations.
run
(run options)
Run a TUI application synchronously (blocks until quit).
Parameters:
| Key | Type | Required | Description |
|---|---|---|---|
:init |
any | Yes | Initial model value |
:update |
function | Yes | (fn [model msg] [new-model cmd]) |
:view |
function | Yes | (fn [model] hiccup) |
:init-cmd |
command | No | Initial command to execute |
:fps |
integer | No | Frames per second (default: 60) |
:alt-screen |
boolean | No | Use alternate screen (default: true) |
Returns: Final model value after quit
Example:
(require '[tui.core :as tui])
(tui/run {:init {:count 0}
:update (fn [model msg]
(if (tui/key= msg "q")
[model tui/quit]
[model nil]))
:view (fn [{:keys [count]}]
[:text (str "Count: " count)])
:fps 30
:alt-screen true})
quit
quit
Constant value returned as a command to exit the application.
Example:
(defn update-fn [model msg]
(if (tui/key= msg "q")
[model tui/quit]
[model nil]))
tick
(tick ms)
Create a command that sends :tick message after a delay.
Parameters:
ms- Delay in milliseconds
Returns: A tick command
Example:
;; Start a 1-second timer
(defn update-fn [model msg]
(case msg
:tick [(update model :seconds inc) (tui/tick 1000)]
[model nil]))
;; Initial tick
(tui/run {:init {:seconds 0}
:update update-fn
:view view
:init-cmd (tui/tick 1000)})
batch
(batch & cmds)
Create a command that executes multiple commands in parallel.
Parameters:
cmds- Variable number of commands
Returns: A batch command
Example:
;; Execute two async operations in parallel
(defn update-fn [model msg]
(if (= msg :start)
[model (tui/batch
(fn [] (fetch-user))
(fn [] (fetch-settings)))]
[model nil]))
sequentially
(sequentially & cmds)
Create a command that executes commands one after another.
Parameters:
cmds- Variable number of commands
Returns: A sequential command
Example:
;; First save, then notify
(defn update-fn [model msg]
(if (= msg :save)
[model (tui/sequentially
(fn [] (save-data model))
(fn [] {:type :saved}))]
[model nil]))
send-msg
(send-msg msg)
Create a command that immediately sends a message.
Parameters:
msg- Message to send
Returns: A send-msg command
Example:
(defn update-fn [model msg]
(if (tui/key= msg "r")
[{:status :resetting} (tui/send-msg :do-reset)]
[model nil]))
key=
(key= msg pattern)
Check if a key message matches a pattern.
Parameters:
msg- The message to checkpattern- Pattern to match (see below)
Returns: true if matches, false otherwise
Pattern types:
| Pattern | Matches |
|---|---|
"q" |
Character 'q' |
:enter |
Enter key |
:up |
Arrow up |
[:ctrl \c] |
Ctrl+C |
[:alt \x] |
Alt+X |
Example:
(defn update-fn [model msg]
(cond
(tui/key= msg "q") [model tui/quit]
(tui/key= msg :up) [(update model :y dec) nil]
(tui/key= msg [:ctrl \c]) [model tui/quit]
:else [model nil]))
key-str
(key-str msg)
Convert a key message to a human-readable string.
Parameters:
msg- Key message
Returns: String representation
Example:
(tui/key-str [:key {:char \a}]) ;; => "a"
(tui/key-str [:key :up]) ;; => "up"
(tui/key-str [:key {:ctrl true :char \c}]) ;; => "ctrl+c"
render
(render hiccup)
Re-exported from tui.render. Render hiccup to ANSI string.
tui.simple
Synchronous runtime compatible with Babashka. Same API as tui.core but without async commands.
run
(run options)
Run a TUI application synchronously.
Parameters:
| Key | Type | Required | Description |
|---|---|---|---|
:init |
any | Yes | Initial model value |
:update |
function | Yes | (fn [model msg] [new-model cmd]) |
:view |
function | Yes | (fn [model] hiccup) |
:alt-screen |
boolean | No | Use alternate screen (default: true) |
Returns: Final model value after quit
Example:
(require '[tui.simple :as tui])
(tui/run {:init 0
:update (fn [model msg]
(cond
(tui/key= msg "q") [model tui/quit]
(tui/key= msg "k") [(inc model) nil]
:else [model nil]))
:view (fn [count]
[:text (str "Count: " count)])})
quit
Same as tui.core/quit.
key=
Same as tui.core/key=.
key-str
Same as tui.core/key-str.
render
Re-exported from tui.render.
tui.render
Converts hiccup data structures to ANSI-formatted strings.
render
(render hiccup)
(render hiccup ctx)
Render hiccup to ANSI string.
Parameters:
hiccup- Hiccup data structurectx- Optional context map (for internal use)
Returns: String with ANSI escape codes
Example:
(require '[tui.render :as r])
(r/render [:text {:fg :red :bold true} "Error!"])
;; => "\e[31m\e[1mError!\e[0m"
(r/render [:col
[:text "Line 1"]
[:text "Line 2"]])
;; => "Line 1\nLine 2"
(r/render [:box {:border :rounded} "Content"])
;; => "╭─────────╮\n│Content │\n╰─────────╯"
text
(text & args)
Helper function to create :text elements.
Example:
(text "Hello") ;; => [:text "Hello"]
(text {:fg :red} "Error") ;; => [:text {:fg :red} "Error"]
row
(row & args)
Helper function to create :row elements.
Example:
(row "A" "B" "C") ;; => [:row "A" "B" "C"]
(row {:gap 2} "A" "B") ;; => [:row {:gap 2} "A" "B"]
col
(col & args)
Helper function to create :col elements.
Example:
(col "Line 1" "Line 2") ;; => [:col "Line 1" "Line 2"]
(col {:gap 1} "A" "B") ;; => [:col {:gap 1} "A" "B"]
box
(box & args)
Helper function to create :box elements.
Example:
(box "Content") ;; => [:box "Content"]
(box {:title "Info"} "Content") ;; => [:box {:title "Info"} "Content"]
tui.input
Parses raw terminal input into structured key messages.
read-key
(read-key)
Read a single key event from the terminal.
Returns: Key message vector [:key ...]
Key message formats:
;; Regular character
[:key {:char \a}]
;; Special key
[:key :enter]
[:key :up]
[:key :f1]
;; Control combination
[:key {:ctrl true :char \c}]
;; Alt combination
[:key {:alt true :char \x}]
;; Unknown sequence
[:key :unknown "\e[xyz"]
Special Key Keywords
| Keyword | Key |
|---|---|
:up |
Arrow Up |
:down |
Arrow Down |
:left |
Arrow Left |
:right |
Arrow Right |
:home |
Home |
:end |
End |
:page-up |
Page Up |
:page-down |
Page Down |
:insert |
Insert |
:delete |
Delete |
:escape |
Escape |
:tab |
Tab |
:shift-tab |
Shift+Tab |
:enter |
Enter |
:backspace |
Backspace |
:f1 - :f12 |
Function keys |
key-match?
(key-match? msg pattern)
Internal function used by key= to match patterns.
key->str
(key->str msg)
Convert key message to string representation.
Example:
(key->str [:key {:char \a}]) ;; => "a"
(key->str [:key :enter]) ;; => "enter"
(key->str [:key {:ctrl true :char \c}]) ;; => "ctrl+c"
(key->str [:key {:alt true :char \x}]) ;; => "alt+x"
tui.terminal
Low-level terminal control functions.
get-terminal-size
(get-terminal-size)
Get the terminal dimensions.
Returns: Map with :width and :height keys
Example:
(require '[tui.terminal :as term])
(term/get-terminal-size)
;; => {:width 120 :height 40}
raw-mode!
(raw-mode!)
Enter raw terminal mode. Disables echo and line buffering.
restore!
(restore!)
Restore terminal to original state.
alt-screen!
(alt-screen!)
Enter the alternate screen buffer.
exit-alt-screen!
(exit-alt-screen!)
Exit the alternate screen buffer.
clear!
(clear!)
Clear the screen and move cursor to home position.
render!
(render! s)
Render a string to the terminal.
Parameters:
s- String to render (typically fromtui.render/render)
Input Functions
(init-input!) ;; Initialize input reader
(close-input!) ;; Close input reader
(input-ready?) ;; Check if input available (non-blocking)
(read-char) ;; Read single character (blocking)
(read-available) ;; Read all available characters
(read-char-timeout ms) ;; Read with timeout
tui.ansi
ANSI escape codes and text styling utilities.
style
(style text & {:keys [fg bg bold dim italic underline inverse strike]})
Apply multiple styles to text.
Parameters:
text- String to style:fg- Foreground color:bg- Background color:bold- Boolean:dim- Boolean:italic- Boolean:underline- Boolean:inverse- Boolean:strike- Boolean
Example:
(require '[tui.ansi :as ansi])
(ansi/style "Error" :fg :red :bold true)
(ansi/style "Warning" :fg :yellow :bg :black :underline true)
Color Functions
(fg color text) ;; Set foreground color
(bg color text) ;; Set background color
(fg-256 n text) ;; 256-color foreground (0-255)
(bg-256 n text) ;; 256-color background (0-255)
(fg-rgb r g b text) ;; True color foreground (24-bit)
(bg-rgb r g b text) ;; True color background (24-bit)
Example:
(ansi/fg :red "Error")
(ansi/bg :yellow "Highlighted")
(ansi/fg-256 208 "Orange")
(ansi/fg-rgb 255 128 0 "True color orange")
String Utilities
(visible-length s) ;; Get visible length (excludes ANSI codes)
(pad-right s width) ;; Pad with spaces on right
(pad-left s width) ;; Pad with spaces on left
(pad-center s width) ;; Center within width
(truncate s max-width) ;; Truncate with ellipsis
Example:
(ansi/visible-length "\e[31mRed\e[0m") ;; => 3
(ansi/pad-right "Hi" 10) ;; => "Hi "
(ansi/pad-center "Hi" 10) ;; => " Hi "
(ansi/truncate "Hello World" 8) ;; => "Hello..."
Cursor Control
(cursor-to row col) ;; Move cursor to position (1-indexed)
(cursor-up n) ;; Move cursor up n lines
(cursor-down n) ;; Move cursor down n lines
(cursor-forward n) ;; Move cursor right n columns
(cursor-back n) ;; Move cursor left n columns
Constants
clear-screen ;; Clear entire screen
clear-line ;; Clear current line
clear-to-end ;; Clear from cursor to end of screen
cursor-home ;; Move cursor to home (1,1)
hide-cursor ;; Hide cursor
show-cursor ;; Show cursor
enter-alt-screen ;; Enter alternate screen buffer
exit-alt-screen ;; Exit alternate screen buffer
cursor-save ;; Save cursor position
cursor-restore ;; Restore cursor position
reset ;; Reset all attributes
Box Drawing Characters
ansi/box-chars
;; => {:rounded {:tl "╭" :tr "╮" :bl "╰" :br "╯" :h "─" :v "│"}
;; :single {:tl "┌" :tr "┐" :bl "└" :br "┘" :h "─" :v "│"}
;; :double {:tl "╔" :tr "╗" :bl "╚" :br "╝" :h "═" :v "║"}
;; :heavy {:tl "┏" :tr "┓" :bl "┗" :br "┛" :h "━" :v "┃"}
;; :ascii {:tl "+" :tr "+" :bl "+" :br "+" :h "-" :v "|"}}
Color Maps
ansi/fg-colors ;; Map of color keywords to ANSI codes
ansi/bg-colors ;; Map of color keywords to ANSI codes
ansi/attrs ;; Map of attribute keywords to ANSI codes
Custom Async Commands
In tui.core, you can create custom async commands by returning functions:
;; Custom command that fetches data
(defn fetch-data-cmd []
(fn []
;; This runs asynchronously
(let [result (http/get "https://api.example.com/data")]
{:type :data-loaded :data (:body result)})))
(defn update-fn [model msg]
(cond
(tui/key= msg "f")
[{:loading true} (fetch-data-cmd)]
(= (:type msg) :data-loaded)
[{:loading false :data (:data msg)} nil]
:else
[model nil]))
The function must:
- Take no arguments
- Return a message (any Clojure value)
- The returned message will be passed to your update function
Summary
| Namespace | Purpose |
|---|---|
tui.core |
Full async runtime with all features |
tui.simple |
Sync runtime for Babashka |
tui.render |
Hiccup to ANSI rendering |
tui.input |
Key input parsing |
tui.terminal |
Low-level terminal control |
tui.ansi |
ANSI codes and text utilities |