Liking cljdoc? Tell your friends :D

com.blockether.vis.ext.channel-tui.terminal-image

Inline terminal image rendering — Kitty graphics protocol / iTerm2 inline images.

The pixel-free logic (capability detection, intrinsic dimension sniffing, cell-box sizing, escape encoding, base64/PNG transcoding) now lives in the lanterna fork's Java class com.googlecode.lanterna.terminal.image.TerminalImage. This namespace is the thin Clojure adapter that keeps vis's map-shaped API ({:images …}, {:w :h}, {:cols :rows}) plus the attachment-aware paste probe, which reaches back into vis internals and so stays here.

The escape strings are emitted DIRECTLY to the tty AFTER Lanterna's delta refresh (the screen loop owns that), placed over rows the renderer reserved as blanks. Lanterna never sees the graphics bytes, so its cell diff stays intact and the image survives subsequent delta frames.

Inline terminal image rendering — Kitty graphics protocol / iTerm2 inline
images.

The pixel-free logic (capability detection, intrinsic dimension sniffing,
cell-box sizing, escape encoding, base64/PNG transcoding) now lives in the
lanterna fork's Java class
`com.googlecode.lanterna.terminal.image.TerminalImage`. This namespace is the
thin Clojure adapter that keeps vis's map-shaped API (`{:images …}`,
`{:w :h}`, `{:cols :rows}`) plus the attachment-aware paste probe, which
reaches back into vis internals and so stays here.

The escape strings are emitted DIRECTLY to the tty AFTER Lanterna's delta
refresh (the screen loop owns that), placed over rows the renderer
reserved as blanks. Lanterna never sees the graphics bytes, so its cell
diff stays intact and the image survives subsequent delta frames.
raw docstring

attachment-cache-dirclj

(attachment-cache-dir)

Durable cache dir (~/.vis/cache/tui-attachments) for persisted image attachments, so a re-rendered history image survives its original (often OS-temp) source path vanishing. Created on demand.

Durable cache dir (`~/.vis/cache/tui-attachments`) for persisted image
attachments, so a re-rendered history image survives its original (often
OS-temp) source path vanishing. Created on demand.
sourceraw docstring

cell-sizeclj

(cell-size {:keys [w h]} max-cols max-rows)

Fit an image of {:w :h} px into max-cols × max-rows cells, aspect-preserving. Returns {:cols :rows} (>= 1).

Fit an image of `{:w :h}` px into `max-cols` × `max-rows` cells,
aspect-preserving. Returns `{:cols :rows}` (>= 1).
sourceraw docstring

detect-capabilitiesclj

(detect-capabilities)
(detect-capabilities env)

Sniff which inline-image protocol the host terminal speaks from env (defaults to the process environment). Returns {:images :kitty|:iterm2|nil}. tmux and screen report nil — they don't reliably forward graphics.

Sniff which inline-image protocol the host terminal speaks from `env`
(defaults to the process environment). Returns `{:images :kitty|:iterm2|nil}`.
tmux and screen report `nil` — they don't reliably forward graphics.
sourceraw docstring

encode-iterm2clj

(encode-iterm2 data {:keys [cols]})

iTerm2 \x1b]1337;File= inline-image sequence for base64 data.

iTerm2 `\x1b]1337;File=` inline-image sequence for base64 `data`.
sourceraw docstring

encode-kittyclj

(encode-kitty data {:keys [cols rows crop-top crop-bottom img-w img-h]})

Kitty graphics \x1b_G transmit+display sequence for base64 data, sized to cols×rows cells. C=1 keeps the cursor put after placement. When crop-top/crop-bottom (cell rows scrolled past the band's top/bottom edge) are positive, only the visible vertical slice is shown at native scale via the Kitty source rectangle, sized from the transmitted image's img-w×img-h pixel dimensions.

Kitty graphics `\x1b_G` transmit+display sequence for base64 `data`, sized to
`cols`×`rows` cells. `C=1` keeps the cursor put after placement. When
`crop-top`/`crop-bottom` (cell rows scrolled past the band's top/bottom edge)
are positive, only the visible vertical slice is shown at native scale via the
Kitty source rectangle, sized from the transmitted image's `img-w`×`img-h`
pixel dimensions.
sourceraw docstring

graphical-terminal?clj

(graphical-terminal?)
(graphical-terminal? env)

Whether we're in a GRAPHICAL terminal — one that speaks an inline-image protocol (kitty/Ghostty/WezTerm/Warp → Kitty, iTerm2 → iTerm2) — as opposed to a plain/non-graphical terminal (or tmux/screen, which mangle graphics pass-through). Callers branch on this to draw an inline image vs. a text-card fallback. The 0-arity reuses the memoized capability detection; pass env to probe an explicit environment (delegates to TerminalImage/isGraphicalTerminal).

Whether we're in a GRAPHICAL terminal — one that speaks an inline-image
protocol (kitty/Ghostty/WezTerm/Warp → Kitty, iTerm2 → iTerm2) — as opposed
to a plain/non-graphical terminal (or tmux/screen, which mangle graphics
pass-through). Callers branch on this to draw an inline image vs. a text-card
fallback. The 0-arity reuses the memoized capability detection; pass `env` to
probe an explicit environment (delegates to `TerminalImage/isGraphicalTerminal`).
sourceraw docstring

image-dimensionsclj

(image-dimensions b mime)

Intrinsic {:w :h} pixel size from the leading bytes of an image, or nil.

Intrinsic `{:w :h}` pixel size from the leading bytes of an image, or nil.
sourceraw docstring

images-protocolclj

(images-protocol)

:kitty, :iterm2, or nil for the current terminal.

`:kitty`, `:iterm2`, or nil for the current terminal.
sourceraw docstring

kitty-delete-placementclj

(kitty-delete-placement id)

Kitty sequence removing image id's placement while KEEPING its uploaded data, so an image scrolled off screen leaves no ghost yet needs no re-upload if it scrolls back into view.

Kitty sequence removing image `id`'s placement while KEEPING its uploaded data,
so an image scrolled off screen leaves no ghost yet needs no re-upload if it
scrolls back into view.
sourceraw docstring

kitty-free-imageclj

(kitty-free-image id)

Kitty sequence deleting image id AND freeing its uploaded data — used when the transmit cache evicts a long-off-screen image to bound terminal-side memory.

Kitty sequence deleting image `id` AND freeing its uploaded data — used when the
transmit cache evicts a long-off-screen image to bound terminal-side memory.
sourceraw docstring

kitty-placeclj

(kitty-place {:keys [id cols rows crop-top crop-bottom img-w img-h]})

Kitty a=p placement sequence for an ALREADY-transmitted image id at the cursor: draw it into a cols×rows cell box, optionally cropped to the visible vertical slice (crop-top/crop-bottom cell rows over an img-w×img-h px image) via the protocol's source rectangle — the SAME x/y/w/h math the fork's crop encodeKitty uses. Reusing placement id p=1 REPLACES the prior placement, so a scroll moves the picture atomically: no delete-all, no re-upload, no flash.

Kitty `a=p` placement sequence for an ALREADY-transmitted image `id` at the
cursor: draw it into a `cols`×`rows` cell box, optionally cropped to the visible
vertical slice (`crop-top`/`crop-bottom` cell rows over an `img-w`×`img-h` px
image) via the protocol's source rectangle — the SAME `x/y/w/h` math the fork's
crop `encodeKitty` uses. Reusing placement id `p=1` REPLACES the prior placement,
so a scroll moves the picture atomically: no delete-all, no re-upload, no flash.
sourceraw docstring

kitty-pngclj

(kitty-png path mime {:keys [width height] :as box})

PNG base64 + transmitted pixel dims {:data :w :h} for the Kitty wire. A PNG file rides through verbatim — transmitted at its intrinsic width×height (and works in the native image too); anything else is transcoded via ImageIO.

PNG base64 + transmitted pixel dims `{:data :w :h}` for the Kitty wire. A PNG
file rides through verbatim — transmitted at its intrinsic `width`×`height`
(and works in the native image too); anything else is transcoded via ImageIO.
sourceraw docstring

kitty-transmitclj

(kitty-transmit data id)

Kitty a=t transmit-ONLY sequence: upload base64 PNG data under client image id id WITHOUT displaying it, chunked into m=1m=0 pieces like the fork's encodeKitty. A later kitty-place draws it with NO re-upload — the key to flicker-free scrolling (transmit once, then re-place cheaply).

Kitty `a=t` transmit-ONLY sequence: upload base64 PNG `data` under client image
id `id` WITHOUT displaying it, chunked into `m=1`…`m=0` pieces like the fork's
`encodeKitty`. A later `kitty-place` draws it with NO re-upload — the key to
flicker-free scrolling (transmit once, then re-place cheaply).
sourceraw docstring

materialize-attachmentclj

(materialize-attachment att)

Decode ONE persisted user image attachment (canonical wire map, STRING keys id/base64/media_type/filename) into a STABLE cache file keyed by its row id and return the descriptor a vis-image fence needs - {:path :mime :filename :size :size-label :width :height} - or nil when it is not a usable still image. Idempotent: an already-written cache file is reused, never rewritten, so a resumed session re-renders the picture from DB-owned bytes even after the original source path is gone. Never throws.

Decode ONE persisted user image attachment (canonical wire map, STRING keys
`id`/`base64`/`media_type`/`filename`) into a STABLE cache file keyed by its
row id and return the descriptor a `vis-image` fence needs -
`{:path :mime :filename :size :size-label :width :height}` - or nil when it is
not a usable still image. Idempotent: an already-written cache file is reused,
never rewritten, so a resumed session re-renders the picture from DB-owned
bytes even after the original source path is gone. Never throws.
sourceraw docstring

parse-cell-size-reportclj

(parse-cell-size-report s)

Parse a terminal window-report reply into {:w :h} CELL pixel dimensions, or nil. Recognises the CSI 16 t cell-size reply ESC[6;<h>;<w>t directly, and falls back to deriving the cell size from a CSI 14 t text-area-pixels reply ESC[4;<hpx>;<wpx>t paired with a CSI 18 t text-area-cells reply ESC[8;<rows>;<cols>t (cell = px / cells). Tolerant of the replies arriving concatenated in any order / interleaved with other bytes.

Parse a terminal window-report reply into `{:w :h}` CELL pixel dimensions, or
nil. Recognises the `CSI 16 t` cell-size reply `ESC[6;<h>;<w>t` directly, and
falls back to deriving the cell size from a `CSI 14 t` text-area-pixels reply
`ESC[4;<hpx>;<wpx>t` paired with a `CSI 18 t` text-area-cells reply
`ESC[8;<rows>;<cols>t` (cell = px / cells). Tolerant of the replies arriving
concatenated in any order / interleaved with other bytes.
sourceraw docstring

probe-dimensionsclj

(probe-dimensions path mime)

Read path's head and sniff its {:w :h} pixel dimensions. nil on failure.

Read `path`'s head and sniff its `{:w :h}` pixel dimensions. nil on failure.
sourceraw docstring

probe-paste-imageclj

(probe-paste-image text {:keys [workspace-root]})

Detect the FIRST image the pasted text points at (a dropped file path). Returns {:path :mime :filename :size :size-label :width :height} or nil. workspace-root anchors relative candidates. Never throws.

Detect the FIRST image the pasted `text` points at (a dropped file path).
Returns `{:path :mime :filename :size :size-label :width :height}` or nil.
`workspace-root` anchors relative candidates. Never throws.
sourceraw docstring

read-base64clj

(read-base64 path)

Read path and base64-encode its bytes, or nil on failure. Cached by path + mtime + size so an unchanged file is encoded at most once.

Read `path` and base64-encode its bytes, or nil on failure. Cached by
path + mtime + size so an unchanged file is encoded at most once.
sourceraw docstring

render-sequenceclj

(render-sequence path mime box)

Full escape sequence that draws the image at path (mime) into a cols×rows cell box for the current terminal, or nil when the terminal can't render inline images / the file can't be decoded. box may carry :crop-top/:crop-bottom (cell rows scrolled past the band edge) plus the image's intrinsic :width/:height, so a partly-scrolled Kitty image renders its visible slice at native scale instead of vanishing.

Full escape sequence that draws the image at `path` (`mime`) into a
`cols`×`rows` cell box for the current terminal, or nil when the terminal
can't render inline images / the file can't be decoded. `box` may carry
`:crop-top`/`:crop-bottom` (cell rows scrolled past the band edge) plus the
image's intrinsic `:width`/`:height`, so a partly-scrolled Kitty image renders
its visible slice at native scale instead of vanishing.
sourceraw docstring

set-cell-dimensions!clj

(set-cell-dimensions! w h)
source

transcode->png-base64clj

(transcode->png-base64 path {:keys [cols rows]})

Decode path (any ImageIO-readable format) and re-encode it as a PNG base64 string, downscaled so it fits the cols×rows cell box in pixels. The Kitty protocol's f=100 only accepts PNG, so a JPEG/GIF/BMP drop must pass through here first. Uses AWT/ImageIO (JVM-only — unavailable in the macOS native image); returns nil on any failure so callers fall back to a text card.

Decode `path` (any ImageIO-readable format) and re-encode it as a PNG
base64 string, downscaled so it fits the `cols`×`rows` cell box in pixels.
The Kitty protocol's `f=100` only accepts PNG, so a JPEG/GIF/BMP drop must
pass through here first. Uses AWT/ImageIO (JVM-only — unavailable in the
macOS native image); returns nil on any failure so callers fall back to a
text card.
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