A self-contained terminal abstraction for a TUI rendering target.
This namespace OWNS the normalized key-event model that downstream TUI code consumes, a pure
(JLine-free) key decoder, a Terminal protocol, a real JLine-backed implementation, and an
atom-backed fake (string-terminal) used for tests.
This is JVM/babashka only (plain .clj).
A self-contained terminal abstraction for a TUI rendering target. This namespace OWNS the normalized key-event model that downstream TUI code consumes, a pure (JLine-free) key decoder, a `Terminal` protocol, a real JLine-backed implementation, and an atom-backed fake (`string-terminal`) used for tests. This is JVM/babashka only (plain `.clj`).
(csi-event rest-ints)Returns [event remaining] for a CSI (ESC [) sequence, given rest-ints (the ints AFTER the
leading 27 91). Returns nil if the sequence is not recognized so the caller can fall back.
Returns `[event remaining]` for a CSI (ESC `[`) sequence, given `rest-ints` (the ints AFTER the leading `27 91`). Returns nil if the sequence is not recognized so the caller can fall back.
(ctrl-letter n)Returns the lowercase letter string for a control code n in 1..26 (1 -> "a" .. 26 -> "z").
Returns the lowercase letter string for a control code `n` in 1..26 (1 -> "a" .. 26 -> "z").
(cursor t)Returns the last recorded cursor map {:x :y :visible?} for the fake terminal t, or nil.
Returns the last recorded cursor map `{:x :y :visible?}` for the fake terminal `t`, or nil.
(cursor-position-string x y)Returns the ANSI escape sequence that moves the cursor to 0-based (x,y). ANSI is 1-based, so
both are incremented.
Returns the ANSI escape sequence that moves the cursor to 0-based (`x`,`y`). ANSI is 1-based, so both are incremented.
(decode-key ints)Decodes the next key from a sequence of input code points ints.
Returns [event remaining-ints], consuming exactly the code points for one key, or nil when
ints is empty. The decoder is pure and contains no JLine/IO dependency. Handles:
:tab; 10 or 13 -> :enter; 8 or 127 -> :backspace:escape27 91 ...) -> arrows, home/end, delete, page-up/down{:ctrl? true :key "a".."z"} (tab/enter handled first)Decodes the next key from a sequence of input code points `ints`.
Returns `[event remaining-ints]`, consuming exactly the code points for one key, or `nil` when
`ints` is empty. The decoder is pure and contains no JLine/IO dependency. Handles:
* printable ASCII / multi-byte unicode code points -> printable event
* 9 -> `:tab`; 10 or 13 -> `:enter`; 8 or 127 -> `:backspace`
* 27 alone (nothing following) -> `:escape`
* CSI cursor/edit sequences (`27 91 ...`) -> arrows, home/end, delete, page-up/down
* control combos 1..26 -> `{:ctrl? true :key "a".."z"}` (tab/enter handled first)(feed! t & events)Enqueues additional scripted key events onto the fake terminal t's read queue.
Enqueues additional scripted key `events` onto the fake terminal `t`'s read queue.
(jline-terminal)Returns a Terminal backed by a system JLine terminal (TerminalBuilder).
Returns a `Terminal` backed by a system JLine terminal (`TerminalBuilder`).
(key-event key)(key-event key opts)Returns a normalized key event map. key is a 1-char string (printable) or a keyword from
special-keys. The remaining values default to a non-modified, non-char event; pass opts
(a map of any of :char :ctrl? :alt? :shift? :raw) to override.
Returns a normalized key event map. `key` is a 1-char string (printable) or a keyword from `special-keys`. The remaining values default to a non-modified, non-char event; pass `opts` (a map of any of `:char :ctrl? :alt? :shift? :raw`) to override.
(output t)Returns the accumulated string written to the fake terminal t.
Returns the accumulated string written to the fake terminal `t`.
(printable-event cp)Returns a printable ::key-event for the unicode code point cp (the :key and :char are the
1-char string for cp).
Returns a printable `::key-event` for the unicode code point `cp` (the `:key` and `:char` are the 1-char string for `cp`).
(resize! t rows cols)Sets the fake terminal t dimensions to rows x cols, then invokes its registered resize handler
(see t-on-resize!), if any — simulating a real terminal's SIGWINCH delivery.
Sets the fake terminal `t` dimensions to `rows` x `cols`, then invokes its registered resize handler (see `t-on-resize!`), if any — simulating a real terminal's SIGWINCH delivery.
(single-codepoint-string? s)Returns true if s is a string consisting of exactly one unicode code point. Note that an
astral/supplementary code point occupies two UTF-16 chars yet is still a single code point, so
this counts code points rather than count (which counts UTF-16 code units).
Returns true if `s` is a string consisting of exactly one unicode code point. Note that an astral/supplementary code point occupies two UTF-16 chars yet is still a single code point, so this counts code points rather than `count` (which counts UTF-16 code units).
The set of keyword values allowed as a special-key :key.
The set of keyword values allowed as a special-key `:key`.
(string-terminal {:keys [rows cols keys sync?] :or {rows 24 cols 80 keys []}})Returns an atom-backed fake Terminal for testing. opts:
:rows - terminal height (default 24):cols - terminal width (default 80):keys - a seq of scripted ::key-events that t-read-key will dequeue, in order:sync? - the boolean reported by t-sync-supported? (default false)Use the accessors output, cursor, feed!, and resize! to drive/inspect it.
Returns an atom-backed fake `Terminal` for testing. `opts`: * `:rows` - terminal height (default 24) * `:cols` - terminal width (default 80) * `:keys` - a seq of scripted `::key-event`s that `t-read-key` will dequeue, in order * `:sync?` - the boolean reported by `t-sync-supported?` (default false) Use the accessors `output`, `cursor`, `feed!`, and `resize!` to drive/inspect it.
Abstraction over a terminal device. Coordinates are 0-based (x column, y row).
Abstraction over a terminal device. Coordinates are 0-based (`x` column, `y` row).
(t-flush! t)Flushes buffered output.
Flushes buffered output.
(t-sync-supported? t)Returns true if synchronized output (DEC 2026 / terminfo Sync) is available.
Returns true if synchronized output (DEC 2026 / terminfo Sync) is available.
(t-leave! t)Restores: shows cursor, leaves alt screen, exits raw mode, closes.
Restores: shows cursor, leaves alt screen, exits raw mode, closes.
(t-size t)Returns {:rows R :cols C}.
Returns `{:rows R :cols C}`.
(t-enter! t)Enters raw mode + alternate screen + hides the cursor.
Enters raw mode + alternate screen + hides the cursor.
(t-write! t s)Writes string s to the terminal (no flush).
Writes string `s` to the terminal (no flush).
(t-set-cursor! t x y visible?)Positions the hardware cursor at 0-based (x,y) and shows/hides it.
Positions the hardware cursor at 0-based (`x`,`y`) and shows/hides it.
(t-read-key t)Returns the next normalized key event (blocking for real terminals), or nil on EOF/empty.
Returns the next normalized key event (blocking for real terminals), or nil on EOF/empty.
(t-on-resize! t handler)Registers zero-arg handler to be invoked when the terminal's size changes (e.g. SIGWINCH on a
real terminal). At most one handler is kept; registering again replaces it. nil clears it.
Registers zero-arg `handler` to be invoked when the terminal's size changes (e.g. SIGWINCH on a real terminal). At most one handler is kept; registering again replaces it. `nil` clears it.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |