666 lines
13 KiB
Markdown
666 lines
13 KiB
Markdown
# API Reference
|
|
|
|
Complete API documentation for Clojure TUI.
|
|
|
|
## Table of Contents
|
|
|
|
- [tui.core](#tuicore) - Main runtime
|
|
- [tui.render](#tuirender) - Hiccup rendering
|
|
- [tui.input](#tuiinput) - Key input parsing
|
|
- [tui.terminal](#tuiterminal) - Terminal control
|
|
- [tui.ansi](#tuiansi) - ANSI escape codes
|
|
|
|
---
|
|
|
|
## tui.core
|
|
|
|
Main runtime using core.async. Provides timers, async commands, background operations, and responsive layout support.
|
|
|
|
### run
|
|
|
|
```clojure
|
|
(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 size] hiccup)` where size is `{:width w :height h}` |
|
|
| `: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:**
|
|
|
|
```clojure
|
|
(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]} _size]
|
|
[:text (str "Count: " count)])
|
|
:fps 30
|
|
:alt-screen true})
|
|
```
|
|
|
|
### quit
|
|
|
|
```clojure
|
|
quit
|
|
```
|
|
|
|
Constant value returned as a command to exit the application.
|
|
|
|
**Example:**
|
|
|
|
```clojure
|
|
(defn update-fn [model msg]
|
|
(if (tui/key= msg "q")
|
|
[model tui/quit]
|
|
[model nil]))
|
|
```
|
|
|
|
### tick
|
|
|
|
```clojure
|
|
(tick ms)
|
|
```
|
|
|
|
Create a command that sends `:tick` message after a delay.
|
|
|
|
**Parameters:**
|
|
- `ms` - Delay in milliseconds
|
|
|
|
**Returns:** A tick command
|
|
|
|
**Example:**
|
|
|
|
```clojure
|
|
;; 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
|
|
|
|
```clojure
|
|
(batch & cmds)
|
|
```
|
|
|
|
Create a command that executes multiple commands in parallel.
|
|
|
|
**Parameters:**
|
|
- `cmds` - Variable number of commands
|
|
|
|
**Returns:** A batch command
|
|
|
|
**Example:**
|
|
|
|
```clojure
|
|
;; 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
|
|
|
|
```clojure
|
|
(sequentially & cmds)
|
|
```
|
|
|
|
Create a command that executes commands one after another.
|
|
|
|
**Parameters:**
|
|
- `cmds` - Variable number of commands
|
|
|
|
**Returns:** A sequential command
|
|
|
|
**Example:**
|
|
|
|
```clojure
|
|
;; 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
|
|
|
|
```clojure
|
|
(send-msg msg)
|
|
```
|
|
|
|
Create a command that immediately sends a message.
|
|
|
|
**Parameters:**
|
|
- `msg` - Message to send
|
|
|
|
**Returns:** A send-msg command
|
|
|
|
**Example:**
|
|
|
|
```clojure
|
|
(defn update-fn [model msg]
|
|
(if (tui/key= msg "r")
|
|
[{:status :resetting} (tui/send-msg :do-reset)]
|
|
[model nil]))
|
|
```
|
|
|
|
### key=
|
|
|
|
```clojure
|
|
(key= msg pattern)
|
|
```
|
|
|
|
Check if a key message matches a pattern.
|
|
|
|
**Parameters:**
|
|
- `msg` - The message to check
|
|
- `pattern` - 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:**
|
|
|
|
```clojure
|
|
(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
|
|
|
|
```clojure
|
|
(key-str msg)
|
|
```
|
|
|
|
Convert a key message to a human-readable string.
|
|
|
|
**Parameters:**
|
|
- `msg` - Key message
|
|
|
|
**Returns:** String representation
|
|
|
|
**Example:**
|
|
|
|
```clojure
|
|
(tui/key-str [:key {:char \a}]) ;; => "a"
|
|
(tui/key-str [:key :up]) ;; => "up"
|
|
(tui/key-str [:key {:ctrl true :char \c}]) ;; => "ctrl+c"
|
|
```
|
|
|
|
### render
|
|
|
|
```clojure
|
|
(render hiccup)
|
|
```
|
|
|
|
Re-exported from `tui.render`. Render hiccup to ANSI string.
|
|
|
|
---
|
|
|
|
## tui.render
|
|
|
|
Converts hiccup data structures to ANSI-formatted strings.
|
|
|
|
### render
|
|
|
|
```clojure
|
|
(render hiccup)
|
|
(render hiccup ctx)
|
|
```
|
|
|
|
Render hiccup to ANSI string.
|
|
|
|
**Parameters:**
|
|
- `hiccup` - Hiccup data structure
|
|
- `ctx` - Optional context map (for internal use)
|
|
|
|
**Returns:** String with ANSI escape codes
|
|
|
|
**Example:**
|
|
|
|
```clojure
|
|
(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
|
|
|
|
```clojure
|
|
(text & args)
|
|
```
|
|
|
|
Helper function to create `:text` elements.
|
|
|
|
**Example:**
|
|
|
|
```clojure
|
|
(text "Hello") ;; => [:text "Hello"]
|
|
(text {:fg :red} "Error") ;; => [:text {:fg :red} "Error"]
|
|
```
|
|
|
|
### row
|
|
|
|
```clojure
|
|
(row & args)
|
|
```
|
|
|
|
Helper function to create `:row` elements.
|
|
|
|
**Example:**
|
|
|
|
```clojure
|
|
(row "A" "B" "C") ;; => [:row "A" "B" "C"]
|
|
(row {:gap 2} "A" "B") ;; => [:row {:gap 2} "A" "B"]
|
|
```
|
|
|
|
### col
|
|
|
|
```clojure
|
|
(col & args)
|
|
```
|
|
|
|
Helper function to create `:col` elements.
|
|
|
|
**Example:**
|
|
|
|
```clojure
|
|
(col "Line 1" "Line 2") ;; => [:col "Line 1" "Line 2"]
|
|
(col {:gap 1} "A" "B") ;; => [:col {:gap 1} "A" "B"]
|
|
```
|
|
|
|
### box
|
|
|
|
```clojure
|
|
(box & args)
|
|
```
|
|
|
|
Helper function to create `:box` elements.
|
|
|
|
**Example:**
|
|
|
|
```clojure
|
|
(box "Content") ;; => [:box "Content"]
|
|
(box {:title "Info"} "Content") ;; => [:box {:title "Info"} "Content"]
|
|
```
|
|
|
|
---
|
|
|
|
## tui.input
|
|
|
|
Parses raw terminal input into structured key messages.
|
|
|
|
### read-key
|
|
|
|
```clojure
|
|
(read-key)
|
|
```
|
|
|
|
Read a single key event from the terminal.
|
|
|
|
**Returns:** Key message vector `[:key ...]`
|
|
|
|
**Key message formats:**
|
|
|
|
```clojure
|
|
;; 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?
|
|
|
|
```clojure
|
|
(key-match? msg pattern)
|
|
```
|
|
|
|
Internal function used by `key=` to match patterns.
|
|
|
|
### key->str
|
|
|
|
```clojure
|
|
(key->str msg)
|
|
```
|
|
|
|
Convert key message to string representation.
|
|
|
|
**Example:**
|
|
|
|
```clojure
|
|
(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
|
|
|
|
```clojure
|
|
(get-terminal-size)
|
|
```
|
|
|
|
Get the terminal dimensions.
|
|
|
|
**Returns:** Map with `:width` and `:height` keys
|
|
|
|
**Example:**
|
|
|
|
```clojure
|
|
(require '[tui.terminal :as term])
|
|
|
|
(term/get-terminal-size)
|
|
;; => {:width 120 :height 40}
|
|
```
|
|
|
|
### raw-mode!
|
|
|
|
```clojure
|
|
(raw-mode!)
|
|
```
|
|
|
|
Enter raw terminal mode. Disables echo and line buffering.
|
|
|
|
### restore!
|
|
|
|
```clojure
|
|
(restore!)
|
|
```
|
|
|
|
Restore terminal to original state.
|
|
|
|
### alt-screen!
|
|
|
|
```clojure
|
|
(alt-screen!)
|
|
```
|
|
|
|
Enter the alternate screen buffer.
|
|
|
|
### exit-alt-screen!
|
|
|
|
```clojure
|
|
(exit-alt-screen!)
|
|
```
|
|
|
|
Exit the alternate screen buffer.
|
|
|
|
### clear!
|
|
|
|
```clojure
|
|
(clear!)
|
|
```
|
|
|
|
Clear the screen and move cursor to home position.
|
|
|
|
### render!
|
|
|
|
```clojure
|
|
(render! s)
|
|
```
|
|
|
|
Render a string to the terminal.
|
|
|
|
**Parameters:**
|
|
- `s` - String to render (typically from `tui.render/render`)
|
|
|
|
### Input Functions
|
|
|
|
```clojure
|
|
(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
|
|
|
|
```clojure
|
|
(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:**
|
|
|
|
```clojure
|
|
(require '[tui.ansi :as ansi])
|
|
|
|
(ansi/style "Error" :fg :red :bold true)
|
|
(ansi/style "Warning" :fg :yellow :bg :black :underline true)
|
|
```
|
|
|
|
### Color Functions
|
|
|
|
```clojure
|
|
(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:**
|
|
|
|
```clojure
|
|
(ansi/fg :red "Error")
|
|
(ansi/bg :yellow "Highlighted")
|
|
(ansi/fg-256 208 "Orange")
|
|
(ansi/fg-rgb 255 128 0 "True color orange")
|
|
```
|
|
|
|
### String Utilities
|
|
|
|
```clojure
|
|
(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:**
|
|
|
|
```clojure
|
|
(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
|
|
|
|
```clojure
|
|
(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
|
|
|
|
```clojure
|
|
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
|
|
|
|
```clojure
|
|
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
|
|
|
|
```clojure
|
|
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:
|
|
|
|
```clojure
|
|
;; 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:
|
|
1. Take no arguments
|
|
2. Return a message (any Clojure value)
|
|
3. The returned message will be passed to your update function
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
| Namespace | Purpose |
|
|
|-----------|---------|
|
|
| `tui.core` | Main runtime with Elm architecture and async commands |
|
|
| `tui.render` | Hiccup to ANSI rendering |
|
|
| `tui.input` | Key input parsing |
|
|
| `tui.terminal` | Low-level terminal control |
|
|
| `tui.ansi` | ANSI codes and text utilities |
|