Files
clojure-tui/docs/api-reference.md
2026-01-22 10:50:26 -05:00

13 KiB

API Reference

Complete API documentation for Clojure TUI.

Table of Contents


tui.core

Main runtime using core.async. Provides timers, async commands, background operations, and responsive layout support.

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 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:

(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

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 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:

(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.render

Converts hiccup data structures to ANSI-formatted strings.

render

(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:

(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 from tui.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:

  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