Liking cljdoc? Tell your friends :D

com.fulcrologic.fulcro.tui.terminal

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`).
raw docstring

csi-eventclj

(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.
sourceraw docstring

csi-u-eventclj

(csi-u-event rest-ints)

Returns [event remaining] for a Kitty/fixterms CSI-u key sequence, given rest-ints (the ints AFTER the leading 27 91). The form is <codepoint> [; <modifiers>] u (final byte u = 117). The modifier field is 1 + bitmask where bit 0 = shift, bit 1 = alt, bit 2 = ctrl. Returns nil when the sequence is not a well-formed CSI-u sequence, so the caller can fall back to csi-event.

:char is populated only for unmodified or shift-only keys (actual text); ctrl/alt combos carry a nil :char, matching the legacy control-code decoding.

Returns `[event remaining]` for a Kitty/fixterms CSI-u key sequence, given `rest-ints` (the ints
AFTER the leading `27 91`). The form is `<codepoint> [; <modifiers>] u` (final byte `u` = 117). The
modifier field is `1 + bitmask` where bit 0 = shift, bit 1 = alt, bit 2 = ctrl. Returns nil when the
sequence is not a well-formed CSI-u sequence, so the caller can fall back to `csi-event`.

`:char` is populated only for unmodified or shift-only keys (actual text); ctrl/alt combos carry a
nil `:char`, matching the legacy control-code decoding.
sourceraw docstring

ctrl-letterclj

(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").
sourceraw docstring

cursorclj

(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.
sourceraw docstring

cursor-position-stringclj

(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.
sourceraw docstring

decode-keyclj

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

  • 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-u sequences (27 91 <cp> [; <mods>] u) -> modified keys with :ctrl?/:alt?/:shift? (Kitty/fixterms enhanced keyboard protocol)
  • 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)
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-u sequences (`27 91 <cp> [; <mods>] u`) -> modified keys with `:ctrl?/:alt?/:shift?`
  (Kitty/fixterms enhanced keyboard protocol)
* 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)
sourceraw docstring

feed!clj

(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.
sourceraw docstring

jline-terminalclj

(jline-terminal)

Returns a Terminal backed by a system JLine terminal (TerminalBuilder).

Returns a `Terminal` backed by a system JLine terminal (`TerminalBuilder`).
sourceraw docstring

key-eventclj

(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.
sourceraw docstring

outputclj

(output t)

Returns the accumulated string written to the fake terminal t.

Returns the accumulated string written to the fake terminal `t`.
sourceraw docstring

printable-eventclj

(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`).
sourceraw docstring

probe-enhanced-keys!clj

(probe-enhanced-keys!)

Diagnostic: builds a system JLine terminal, sends the Kitty/CSI-u progressive-enhancement query, reads whatever the terminal replies (no alt-screen, no shortcut handling), restores the terminal, and PRINTS the raw reply bytes and the OK/not-OK verdict to stdout. Run this directly in the terminal you want to test (e.g. clojure -e "((requiring-resolve 'com.fulcrologic.fulcro.tui.terminal/probe-enhanced-keys!))"). A conforming terminal replies ESC [ ? <flags> u (bytes start 27 91 63, end 117).

Diagnostic: builds a system JLine terminal, sends the Kitty/CSI-u progressive-enhancement query,
reads whatever the terminal replies (no alt-screen, no shortcut handling), restores the terminal,
and PRINTS the raw reply bytes and the OK/not-OK verdict to stdout. Run this directly in the
terminal you want to test (e.g. `clojure -e "((requiring-resolve 'com.fulcrologic.fulcro.tui.terminal/probe-enhanced-keys!))"`).
A conforming terminal replies `ESC [ ? <flags> u` (bytes start `27 91 63`, end `117`).
sourceraw docstring

probe-key!clj

(probe-key!)
(probe-key! n)

Diagnostic: builds a system JLine terminal, ENABLES the enhanced keyboard protocol (same push the driver does), then reads n (default 8) keypresses and prints, for each, the raw code points and the decode-key result. Use this to see what a terminal actually sends for a chord like Alt-s AFTER the protocol is enabled — a Kitty-conforming terminal sends ESC [ <cp> ; <mods> u; iTerm with Left-Option set to compose sends a single composed code point and NO :alt?.

Run directly in the target terminal, press the keys to test, then press q: clojure -e "((requiring-resolve 'com.fulcrologic.fulcro.tui.terminal/probe-key!))"

Diagnostic: builds a system JLine terminal, ENABLES the enhanced keyboard protocol (same push the
driver does), then reads `n` (default 8) keypresses and prints, for each, the raw code points and
the `decode-key` result. Use this to see what a terminal actually sends for a chord like Alt-s
AFTER the protocol is enabled — a Kitty-conforming terminal sends `ESC [ <cp> ; <mods> u`; iTerm
with Left-Option set to compose sends a single composed code point and NO `:alt?`.

Run directly in the target terminal, press the keys to test, then press `q`:
`clojure -e "((requiring-resolve 'com.fulcrologic.fulcro.tui.terminal/probe-key!))"`
sourceraw docstring

read-decimalclj

(read-decimal v)

Returns [n remaining] for the leading run of ASCII decimal digits in v (a vector of ints), or nil when v does not start with a digit.

Returns `[n remaining]` for the leading run of ASCII decimal digits in `v` (a vector of ints), or
nil when `v` does not start with a digit.
sourceraw docstring

resize!clj

(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.
sourceraw docstring

single-codepoint-string?clj

(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).
sourceraw docstring

special-keysclj

The set of keyword values allowed as a special-key :key.

The set of keyword values allowed as a special-key `:key`.
sourceraw docstring

string-terminalclj

(string-terminal {:keys [rows cols keys sync? enhanced-keys?]
                  :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)
  • :enhanced-keys? - the boolean reported by t-enhanced-keys? (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)
* `:enhanced-keys?` - the boolean reported by `t-enhanced-keys?` (default false)

Use the accessors `output`, `cursor`, `feed!`, and `resize!` to drive/inspect it.
sourceraw docstring

Terminalcljprotocol

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-enhanced-keys?clj

(t-enhanced-keys? t)

Returns true if the enhanced (Kitty/fixterms CSI-u) keyboard protocol was detected and enabled for this terminal (so modified keys arrive reliably as CSI-u sequences). False otherwise; the keyboard-shortcut layer is gated on this.

Returns true if the enhanced (Kitty/fixterms CSI-u) keyboard protocol was detected and enabled
for this terminal (so modified keys arrive reliably as CSI-u sequences). False otherwise; the
keyboard-shortcut layer is gated on this.

t-flush!clj

(t-flush! t)

Flushes buffered output.

Flushes buffered output.

t-sync-supported?clj

(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!clj

(t-leave! t)

Restores: shows cursor, leaves alt screen, exits raw mode, closes.

Restores: shows cursor, leaves alt screen, exits raw mode, closes.

t-sizeclj

(t-size t)

Returns {:rows R :cols C}.

Returns `{:rows R :cols C}`.

t-enter!clj

(t-enter! t)

Enters raw mode + alternate screen + hides the cursor.

Enters raw mode + alternate screen + hides the cursor.

t-write!clj

(t-write! t s)

Writes string s to the terminal (no flush).

Writes string `s` to the terminal (no flush).

t-set-cursor!clj

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

(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!clj

(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.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close