Liking cljdoc? Tell your friends :D
Clojure only.

com.blockether.vis.ext.channel-tui.primitives

Low-level drawing primitives wrapping Lanterna TextGraphics. All rendering code should use these instead of raw Java interop.

Width-math contract

String width here means display columns the terminal will paint, NOT Java .length() and NOT (count s). Those count UTF-16 code units; a single emoji like 📁 is two code units but two columns, a CJK glyph like 日 is one code unit but two columns, a flag sequence 🇵🇱 is four code units, one grapheme, two columns. Mix the two and your alignment drifts.

Use display-width and truncate-cols for any string that could contain non-ASCII. Plain count/subs are still allowed for ASCII internals (box-drawing strings we authored, single-glyph keystroke labels, etc.) where the answer is identical and the call is a hot path.

Low-level drawing primitives wrapping Lanterna TextGraphics.
All rendering code should use these instead of raw Java interop.

Width-math contract
===================

String width here means **display columns the terminal will paint**,
NOT Java `.length()` and NOT (count s). Those count UTF-16 code units;
a single emoji like 📁 is two code units but two columns,
a CJK glyph like 日 is one code unit but two columns, a flag
sequence 🇵🇱 is four code units, one grapheme,
two columns. Mix the two and your alignment drifts.

Use `display-width` and `truncate-cols` for any string that could
contain non-ASCII. Plain `count`/`subs` are still allowed for ASCII
internals (box-drawing strings we authored, single-glyph keystroke
labels, etc.) where the answer is identical and the call is a hot path.
raw docstring

alignclj

(align s width mode)

Align s to width display columns by mode: :left pad on the right (default for any unknown mode) :right pad on the left :center pad both sides :justify full-justify the words (flush both margins).

Align `s` to `width` display columns by `mode`:
:left    pad on the right (default for any unknown mode)
:right   pad on the left
:center  pad both sides
:justify full-justify the words (flush both margins).
sourceraw docstring

source

BOLDclj

source

BORDEREDclj

source

BOX_BLclj

source

BOX_BRclj

source

BOX_Hclj

source

BOX_T_Lclj

source

BOX_T_Rclj

source

BOX_TLclj

source

BOX_TRclj

source

BOX_Vclj

source

center-textclj

(center-text s w)

Center string within w terminal columns, padding both sides. Truncates (column-aware) if too wide.

Center string within `w` terminal columns, padding both sides.
Truncates (column-aware) if too wide.
sourceraw docstring

clear-styles!clj

(clear-styles! g)

Remove all active text styles.

Remove all active text styles.
sourceraw docstring

col-prefix-endclj

(col-prefix-end s max-cols)

Return the char-index i such that (subs s 0 i) is the longest prefix of s whose display-width is <= max-cols AND that does NOT split a grapheme cluster.

Use this when you need both the prefix and the position of the un-consumed remainder (e.g. in word-wrapping). For just the prefix, truncate-cols is friendlier.

Returns 0 for nil/empty or non-positive max-cols.

Return the char-index `i` such that `(subs s 0 i)` is the longest
prefix of `s` whose `display-width` is <= `max-cols` AND that does NOT
split a grapheme cluster.

Use this when you need both the prefix and the position of the
un-consumed remainder (e.g. in word-wrapping). For just the prefix,
`truncate-cols` is friendlier.

Returns 0 for nil/empty or non-positive `max-cols`.
sourceraw docstring

CROSSED-OUTclj

source

cursor-posclj

(cursor-pos col row)

Create a TerminalPosition for cursor placement.

Create a TerminalPosition for cursor placement.
sourceraw docstring

disable!clj

(disable! g & modifiers)

Disable one or more text styles.

Disable one or more text styles.
sourceraw docstring

display-widthclj

(display-width s)

Number of terminal columns s will occupy when painted by lanterna.

Built on TextCharacter/fromString, the same routine AbstractTextGraphics.putString uses internally after PR #625, so what we measure matches what the renderer actually paints - grapheme clusters honoured (BreakIterator-based), CJK + emoji counted as two columns, ASCII as one.

Inline span sentinels (INLINE_*_ON/OFF, range ...) count as zero columns: they're invisible style toggles, never painted, never advance the cursor.

Stray ASCII control bytes (0x00-0x1F) get sanitized to / before reaching Lanterna - see sanitize-control-chars for the why. Without that, a single rogue in a paint string used to take down the entire render thread.

Returns 0 for nil/empty input.

Number of terminal columns `s` will occupy when painted by lanterna.

   Built on `TextCharacter/fromString`, the same routine
   `AbstractTextGraphics.putString` uses internally after PR #625, so
   what we measure matches what the renderer actually paints - grapheme
   clusters honoured (BreakIterator-based), CJK + emoji counted as two
   columns, ASCII as one.

   Inline span sentinels (`INLINE_*_ON`/`OFF`, range ...)
   count as zero columns: they're invisible style toggles, never
   painted, never advance the cursor.

   Stray ASCII control bytes (0x00-0x1F) get sanitized to `/`
   before reaching Lanterna - see `sanitize-control-chars` for the
   why. Without that, a single rogue `
` in a paint string used to
   take down the entire render thread.

   Returns 0 for nil/empty input.
sourceraw docstring

dot-cell!clj

(dot-cell! g col row fg)

Overlay a bottom-flush mark in fg colour onto the SINGLE cell at (col,row), keeping its existing background, but ONLY when that cell is currently a blank space OR an existing mark. (LOWER ONE EIGHTH BLOCK) sits flush on the cell's bottom edge — the SAME row as an underline-cell! border — so the running tab's marching marks line up with the ready tab's underline instead of floating one line high like a baseline . did (which read as flicker). Only blank padding cells are touched, so the number, | separator, label, and close ✕ (non-blank) are never clobbered — but a prior may be RE-COLOURED, which lets a running tab paint a dim base line then overlay a bright marching band on top. No-op off-screen or over any non-blank glyph.

Overlay a bottom-flush `▁` mark in `fg` colour onto the SINGLE cell at
(col,row), keeping its existing background, but ONLY when that cell is
currently a blank space OR an existing `▁` mark. `▁` (LOWER ONE EIGHTH
BLOCK) sits flush on the cell's bottom edge — the SAME row as an
`underline-cell!` border — so the
running tab's marching marks line up with the ready tab's underline instead
of floating one line high like a baseline `.` did (which read as flicker).
Only blank padding cells are touched, so the number, ` | ` separator,
label, and close ✕ (non-blank) are never clobbered — but a prior `▁` may be
RE-COLOURED, which lets a running tab paint a dim base line then overlay a
bright marching band on top. No-op off-screen or over
any non-blank glyph.
sourceraw docstring

draw-box!clj

(draw-box! g left top w h)

Draw a single-line bordered box at (left, top) of size wxh. Draws corners, edges. Does NOT fill interior.

Draw a single-line bordered box at (left, top) of size wxh.
Draws corners, edges. Does NOT fill interior.
sourceraw docstring

draw-centered!clj

(draw-centered! g left row width text)

Draw text centered at row within [left, left+width).

Draw text centered at row within [left, left+width).
sourceraw docstring

draw-selection-marker!clj

(draw-selection-marker! g col row selected?)
(draw-selection-marker! g col row selected? marker-fg)

Paint the selection marker at (col, row) when selected? is truthy. Unselected rows get nothing — the surrounding row fill is expected to already cover those cells.

The glyph is rendered BOLD. Provide marker-fg to give it its own color (e.g. dialog-hint-key); when omitted, whatever fg is currently set on g is used.

See the Selection marker block above for the project-wide rationale. Callers that need the prefix as a STRING (to inline into a row label) should use selection-prefix instead.

Paint the selection marker at (col, row) when `selected?` is
truthy. Unselected rows get nothing — the surrounding row fill is
expected to already cover those cells.

The glyph is rendered BOLD. Provide `marker-fg` to give it its
own color (e.g. `dialog-hint-key`); when omitted, whatever fg is
currently set on `g` is used.

See the `Selection marker` block above for the project-wide
rationale. Callers that need the prefix as a STRING (to inline
into a row label) should use `selection-prefix` instead.
sourceraw docstring

draw-separator!clj

(draw-separator! g left right row)

Draw a horizontal separator with T-junctions at left/right edges.

Draw a horizontal separator with T-junctions at left/right edges.
sourceraw docstring

draw-space-around!clj

(draw-space-around! g left row width items)

Draw items spread across row within [left, left+width) with space-around.

Draw items spread across row within [left, left+width) with space-around.
sourceraw docstring

draw-space-between!clj

(draw-space-between! g left row width items)

Draw items spread across row within [left, left+width) with space-between.

Draw items spread across row within [left, left+width) with space-between.
sourceraw docstring

draw-tabs!clj

(draw-tabs! g
            tabs
            {:keys [left row width active-id gap fg bg active-fg active-bg
                    inactive-fg inactive-bg bordered?]})

Draw a tab strip and return its geometry.

Required opts: :left, :row, :width, :active-id, :fg, :bg, :active-fg, :active-bg, :inactive-fg, :inactive-bg. Optional: :gap, :bordered?.

This primitive knows layout and drawing only. Callers own domain actions and click-region registration.

Draw a tab strip and return its geometry.

Required opts: `:left`, `:row`, `:width`, `:active-id`, `:fg`, `:bg`,
`:active-fg`, `:active-bg`, `:inactive-fg`, `:inactive-bg`.
Optional: `:gap`, `:bordered?`.

This primitive knows layout and drawing only. Callers own domain actions and
click-region registration.
sourceraw docstring

enable!clj

(enable! g & modifiers)

Enable one or more text styles. modifiers are SGR constants (BOLD, ITALIC, etc.).

Enable one or more text styles. `modifiers` are SGR constants (BOLD, ITALIC, etc.).
sourceraw docstring

fill-rect!clj

(fill-rect! g col row w h)
(fill-rect! g col row w h ch)

Fill a rectangle at (col, row) of size wxh with the given char (default space).

Fill a rectangle at (col, row) of size wxh with the given char (default space).
sourceraw docstring

fold-colsclj

(fold-cols s max-cols)

Character-fold s into a vector of segments, each at most max-cols display columns wide, never splitting a grapheme cluster.

This is a terminal-style SOFT WRAP, the soft-wrap primitive shared by the agent code rail and the tool-result code blocks: unlike word-wrap it never drops or reflows whitespace — the bytes are preserved exactly and a break is inserted only at the column boundary. So a pathologically wide single line (a one-line git_commit message arg, a wide clj_eval value map) folds at the bubble edge instead of overflowing or being clipped, while indentation and in-row column alignment survive.

The fold itself is lanterna's TerminalTextUtils/foldColumns — the same grapheme/EAW-aware text-flow family the screen paints with (displayWidth / wordWrap / justify). A line already within budget comes back [s] unchanged, so normal multi-line source is untouched and only the over-wide rows fold. nil/empty returns [""].

Input carrying an ESC (0x1b) is returned unfolded — foldColumns is plain-text-only (the grapheme splitter throws on ESC); callers that need ANSI-aware width clip such rows separately.

Character-fold `s` into a vector of segments, each at most `max-cols`
display columns wide, never splitting a grapheme cluster.

This is a terminal-style SOFT WRAP, the soft-wrap primitive shared by
the agent code rail and the tool-result code blocks: unlike word-wrap it
never drops or reflows whitespace — the bytes are preserved exactly and a
break is inserted only at the column boundary. So a pathologically wide
single line (a one-line `git_commit` message arg, a wide `clj_eval`
value map) folds at the bubble edge instead of overflowing or being
clipped, while indentation and in-row column alignment survive.

The fold itself is lanterna's `TerminalTextUtils/foldColumns` — the same
grapheme/EAW-aware text-flow family the screen paints with (`displayWidth`
/ `wordWrap` / `justify`). A line already within budget comes back `[s]`
unchanged, so normal multi-line source is untouched and only the over-wide
rows fold. nil/empty returns `[""]`.

Input carrying an ESC (0x1b) is returned unfolded — `foldColumns` is
plain-text-only (the grapheme splitter throws on ESC); callers that need
ANSI-aware width clip such rows separately.
sourceraw docstring

GLYPH_DIRclj

source

GLYPH_RESOURCESclj

source

horiz-lineclj

(horiz-line n)

Return a string of n horizontal box-drawing chars.

Return a string of `n` horizontal box-drawing chars.
sourceraw docstring

inline-sentinel?clj

(inline-sentinel? g)

True when g (a single grapheme String) is one of the eight inline span sentinels above. Cheap range check, no map lookup.

True when `g` (a single grapheme String) is one of the eight inline
span sentinels above. Cheap range check, no map lookup.
sourceraw docstring

INLINE_BOLD_OFFclj

source

INLINE_BOLD_ONclj

source

INLINE_CODE_OFFclj

source

INLINE_CODE_ONclj

source

INLINE_ITALIC_OFFclj

source

INLINE_ITALIC_ONclj

source

source

source

INLINE_STRIKE_OFFclj

source

INLINE_STRIKE_ONclj

source

ITALICclj

source

justifyclj

(justify s width)
(justify s width justify-last?)

Word-wrap s to width columns, then FULL-JUSTIFY every line, leaving each paragraph's final line left-aligned (the standard typographic convention). Pass justify-last? true to stretch the final line too. Returns a vec of lines.

Word-wrap `s` to `width` columns, then FULL-JUSTIFY every line, leaving each
paragraph's final line left-aligned (the standard typographic convention).
Pass `justify-last?` true to stretch the final line too. Returns a vec of
lines.
sourceraw docstring

justify-lineclj

(justify-line line width)

Full-justify the words on line to EXACTLY width display columns by distributing inter-word spaces (flush to both margins). A blank or single-word line is left-aligned (right-padded) instead — nothing to stretch.

Full-justify the words on `line` to EXACTLY `width` display columns by
distributing inter-word spaces (flush to both margins). A blank or
single-word line is left-aligned (right-padded) instead — nothing to
stretch.
sourceraw docstring

MARK_ACTIONclj

source

MARK_VALUEclj

source

MARKER_ANSWER_HDRclj

source

MARKER_ANSWER_PADclj

source

MARKER_ANSWER_SEPclj

source

MARKER_ANSWER_TXTclj

source

MARKER_CODEclj

source

MARKER_CODE_ERRclj

source

MARKER_CODE_ERR_PADclj

source

MARKER_CODE_OKclj

source

MARKER_CODE_OK_PADclj

source

MARKER_CODE_PADclj

source

MARKER_DURATIONclj

source

MARKER_ERR_RESULTclj

source

MARKER_HINTclj

source

MARKER_ITERATION_HDRclj

source

MARKER_ITERATION_PADclj

source

MARKER_MD_BOLDclj

source

MARKER_MD_BULLETclj

source

MARKER_MD_CODEclj

source

MARKER_MD_H1clj

source

MARKER_MD_H2clj

source

MARKER_MD_H3clj

source

MARKER_MD_HRclj

source

MARKER_MD_QUOTEclj

source

MARKER_MD_SUMMARYclj

source

MARKER_MD_TABLE_HEADclj

source

MARKER_MD_TABLE_ROWclj

source

MARKER_MD_TABLE_SEPclj

source

MARKER_OP_ROWclj

source

MARKER_QUEUE_BORDERclj

source

MARKER_QUEUE_HDRclj

source

MARKER_QUEUE_ITEMclj

source

MARKER_RECAPclj

source

MARKER_RESULTclj

source

MARKER_SEPclj

source

MARKER_TH_MD_BOLDclj

source

MARKER_TH_MD_BULLETclj

source

MARKER_TH_MD_CODEclj

source

MARKER_TH_MD_H1clj

source

MARKER_TH_MD_H2clj

source

MARKER_TH_MD_H3clj

source

MARKER_TH_MD_HRclj

source

MARKER_TH_MD_QUOTEclj

source

MARKER_TH_MD_SUMMARYclj

source

MARKER_TH_MD_TABLE_HEADclj

source

MARKER_TH_MD_TABLE_ROWclj

source

MARKER_TH_MD_TABLE_SEPclj

source

MARKER_THINKINGclj

source

pad-leftclj

(pad-left s w)

Pad string to w terminal columns, left-filling with spaces. Truncates (column-aware) if too wide.

Pad string to `w` terminal columns, left-filling with spaces.
Truncates (column-aware) if too wide.
sourceraw docstring

pad-rightclj

(pad-right s w)

Pad string to w terminal columns, right-filling with spaces. Truncates (column-aware) if too wide.

Pad string to `w` terminal columns, right-filling with spaces.
Truncates (column-aware) if too wide.
sourceraw docstring

paint-styled-line!clj

(paint-styled-line! g x y line base-fg base-bg code-fg code-bg)

Paint a single line at (x, y) honouring inline span sentinels.

The line may contain interleaved text and INLINE_*_ON/OFF sentinels (range \uE110...\uE117). Sentinels themselves are NEVER painted; they toggle the SGR style (BOLD/ITALIC/CROSSED-OUT) or the fg/bg colors (CODE) for the spans that follow.

base-fg / base-bg are the colors used for non-code spans. Code spans force code-fg / code-bg until INLINE_CODE_OFF.

Robustness contract:

  • Walks by GRAPHEME CLUSTER (lanterna's TextCharacter/fromString), so column tracking is exact for emoji + CJK.
  • INHERITS any SGR modifiers already enabled on g at entry (e.g. a wrapping (p/styled g [p/ITALIC] ...) for blockquotes). Inline toggles STACK on top of the inherited set: > **bold** inside a quote renders as bold-italic, not bold-without-italic. The pre-fix version called clearModifiers at entry and silently dropped the wrapping italic - user-visible bug on every blockquote that contained inline emphasis.
  • Unmatched / dangling sentinels (e.g. an OFF without a prior ON, or a line that ends mid-bold) are tolerated: at exit we restore exactly the inherited modifier set, so SGR state never leaks past the call.
  • When NO sentinel appears in the line this collapses to a single put-str! call - the same as the old non-styled path - so the hot path is not penalised for the common case.

This is the entry point that lets the markdown renderer support bold / italic / ~~strike~~ / code mid-line without replacing the marker-prefix-per-line architecture above.

Paint a single line at (x, y) honouring inline span sentinels.

The line may contain interleaved text and `INLINE_*_ON`/`OFF`
sentinels (range \uE110...\uE117). Sentinels themselves are NEVER
painted; they toggle the SGR style (BOLD/ITALIC/CROSSED-OUT) or
the fg/bg colors (CODE) for the spans that follow.

`base-fg` / `base-bg` are the colors used for non-code spans.
Code spans force `code-fg` / `code-bg` until INLINE_CODE_OFF.

Robustness contract:
- Walks by GRAPHEME CLUSTER (lanterna's `TextCharacter/fromString`),
  so column tracking is exact for emoji + CJK.
- INHERITS any SGR modifiers already enabled on `g` at entry (e.g.
  a wrapping `(p/styled g [p/ITALIC] ...)` for blockquotes). Inline
  toggles STACK on top of the inherited set: `> **bold**` inside a
  quote renders as bold-italic, not bold-without-italic. The pre-fix
  version called `clearModifiers` at entry and silently dropped the
  wrapping italic - user-visible bug on every blockquote that
  contained inline emphasis.
- Unmatched / dangling sentinels (e.g. an OFF without a prior ON,
  or a line that ends mid-bold) are tolerated: at exit we restore
  exactly the inherited modifier set, so SGR state never leaks past
  the call.
- When NO sentinel appears in the line this collapses to a single
  `put-str!` call - the same as the old non-styled path - so the
  hot path is not penalised for the common case.

This is the entry point that lets the markdown renderer support
**bold** / *italic* / ~~strike~~ / `code` mid-line without
replacing the marker-prefix-per-line architecture above.
sourceraw docstring

put-str!clj

(put-str! g col row text)

Draw a string at (col, row). Control characters are sanitized.

Draw a string at (col, row). Control characters are sanitized.
sourceraw docstring

REVERSEclj

source

selection-prefixclj

(selection-prefix selected?)

Return the leading marker string for a list/menu row.

Use this for rows where the marker can be inlined into the body text (simple list items, checkbox rows, slash-command rows). For rows where the marker must live OUTSIDE a fixed-column body (file/session pickers, provider/model cards) call draw-selection-marker! from the caller's row loop instead.

Return the leading marker string for a list/menu row.

Use this for rows where the marker can be inlined into the body
text (simple list items, checkbox rows, slash-command rows). For
rows where the marker must live OUTSIDE a fixed-column body
(file/session pickers, provider/model cards) call
`draw-selection-marker!` from the caller's row loop instead.
sourceraw docstring

SELECTION_BLANKclj

source

SELECTION_GLYPHclj

Two-col selection marker. Selected rows show +space, unselected rows show two spaces, so the body content stays column-aligned.

The glyph MUST be display-width 1 so glyph+space == 2 cols and exactly fills the reserved gutter. (U+2022) is East-Asian ambiguous width; the lanterna fork (>= 3.1.5-vis.7) scores EAW=A as NARROW by default, so is 2 cols. (A regression in vis.6 briefly made it wide — the 'marker eats a character' bug.)

Two-col selection marker. Selected rows show `•`+space, unselected
rows show two spaces, so the body content stays column-aligned.

The glyph MUST be display-width 1 so glyph+space == 2 cols and
exactly fills the reserved gutter. `•` (U+2022) is East-Asian
*ambiguous* width; the lanterna fork (>= 3.1.5-vis.7) scores EAW=A
as NARROW by default, so `• ` is 2 cols. (A regression in vis.6
briefly made it wide — the 'marker eats a character' bug.)
sourceraw docstring

SELECTION_WIDTHclj

source

set-bg!clj

(set-bg! g color)
source

set-char!clj

(set-char! g col row ch)

Draw a single character at (col, row).

Draw a single character at (col, row).
sourceraw docstring

set-colors!clj

(set-colors! g fg bg)

Set both foreground and background color in one call.

Set both foreground and background color in one call.
sourceraw docstring

set-fg!clj

(set-fg! g color)
source

space-aroundclj

(space-around items w)

Distribute items across w terminal columns with equal space around each item. Like CSS justify-content: space-around.

Distribute items across `w` terminal columns with equal space
around each item. Like CSS justify-content: space-around.
sourceraw docstring

space-betweenclj

(space-between items w)

Distribute items across w terminal columns with equal gaps. First item flush-left, last item flush-right, rest evenly spaced. Like CSS justify-content: space-between.

Distribute items across `w` terminal columns with equal gaps.
First item flush-left, last item flush-right, rest evenly spaced.
Like CSS justify-content: space-between.
sourceraw docstring

status-mark!clj

(status-mark! g col row glyph fg bg)

Paint a 1-col status glyph in colour fg on bg at (col,row) and return the next col (col + STATUS_WIDTH) so the caller can place the label right after. The reusable mark behind settings rows + resource rows.

Paint a 1-col status `glyph` in colour `fg` on `bg` at (col,row) and return
the next col (`col + STATUS_WIDTH`) so the caller can place the label right
after. The reusable mark behind settings rows + resource rows.
sourceraw docstring

STATUS_OFFclj

source

STATUS_ONclj

source

STATUS_WIDTHclj

source

styledcljmacro

(styled g styles & body)

Draw with styles temporarily enabled. Restores previous styles after body. Usage: (styled g [BOLD ITALIC] (put-str! g 0 0 "hello"))

Draw with styles temporarily enabled. Restores previous styles after body.
Usage: (styled g [BOLD ITALIC] (put-str! g 0 0 "hello"))
sourceraw docstring

tab-atclj

(tab-at layout col)

Return the tab geometry under col, or nil. Expects tab-layout output.

Return the tab geometry under `col`, or nil. Expects `tab-layout` output.
sourceraw docstring

tab-display-labelclj

(tab-display-label {:keys [id label dirty? state]})

Compact label for a tab map.

Supported tab keys:

  • :label / :id - visible base label.
  • :dirty? - appends a dirty marker.
  • :state - appends a compact state badge for running / verified / accepted / error tabs.

This is terminal-column aware when later passed through tab-layout, so callers may use emoji or CJK labels without hand-padding.

Compact label for a tab map.

Supported tab keys:
- `:label` / `:id` - visible base label.
- `:dirty?` - appends a dirty marker.
- `:state` - appends a compact state badge for running / verified /
  accepted / error tabs.

This is terminal-column aware when later passed through `tab-layout`, so
callers may use emoji or CJK labels without hand-padding.
sourceraw docstring

tab-layoutclj

(tab-layout tabs left width active-id)
(tab-layout tabs left width active-id {:keys [gap]})

Return tab geometry for a horizontal tab strip.

tabs is a seq of maps. Returned maps include :left, :width, :active?, and :text truncated to fit :width. Width math uses terminal columns, not Java chars. When the strip is too narrow, later tabs may get zero width; draw helpers skip those safely.

Return tab geometry for a horizontal tab strip.

`tabs` is a seq of maps. Returned maps include `:left`, `:width`,
`:active?`, and `:text` truncated to fit `:width`. Width math uses terminal
columns, not Java chars. When the strip is too narrow, later tabs may get
zero width; draw helpers skip those safely.
sourceraw docstring

truncate-colsclj

(truncate-cols s max-cols)

Return the longest prefix of s that fits in at most max-cols terminal columns, never splitting a grapheme cluster.

Edge cases honoured:

  • nil or max-cols <= 0 returns "".
  • If a double-width grapheme would straddle the cut, it is dropped (NOT half-included), and one space is appended in its place so the returned string's display-width is exactly max-cols. This keeps pad-right / pad-left idempotent under repeated truncation.
Return the longest prefix of `s` that fits in at most `max-cols`
terminal columns, never splitting a grapheme cluster.

Edge cases honoured:
- nil or `max-cols <= 0` returns `""`.
- If a double-width grapheme would straddle the cut, it is dropped
  (NOT half-included), and one space is appended in its place so the
  returned string's `display-width` is exactly `max-cols`. This keeps
  `pad-right` / `pad-left` idempotent under repeated truncation.
sourceraw docstring

UNDERLINEclj

source

underline-cell!clj

(underline-cell! g col row)
(underline-cell! g col row fg)

Add the UNDERLINE modifier to the SINGLE already-painted cell at (col,row), preserving its glyph + background. Reads the cell back via getCharacter and re-sets it with the modifier folded in, so callers can paint a PER-COLUMN border (a steady / marching underline) that the global enable!/UNDERLINE attribute — which would underline every cell touched after it — can't express. No-op when the cell is empty/off-screen.

3-arity keeps the cell's own foreground (the underline inherits it). 4-arity RECOLOURS the foreground to fg first, so the underline — which a terminal draws in the cell's foreground colour — renders in fg. Recolour is uniform across blank padding AND glyph cells, giving ONE consistent underline shape/weight everywhere (no block-glyph vs SGR-line mismatch).

Add the UNDERLINE modifier to the SINGLE already-painted cell at (col,row),
preserving its glyph + background. Reads the cell back via `getCharacter`
and re-sets it with the modifier folded in, so callers can paint a
PER-COLUMN border (a steady / marching underline) that the global
`enable!`/`UNDERLINE` attribute — which would underline every cell touched
after it — can't express. No-op when the cell is empty/off-screen.

3-arity keeps the cell's own foreground (the underline inherits it).
4-arity RECOLOURS the foreground to `fg` first, so the underline — which a
terminal draws in the cell's foreground colour — renders in `fg`. Recolour
is uniform across blank padding AND glyph cells, giving ONE consistent
underline shape/weight everywhere (no block-glyph vs SGR-line mismatch).
sourceraw docstring

v-center-offsetclj

(v-center-offset content-h container-h)

Compute vertical offset to center content-h rows within container-h rows.

Compute vertical offset to center `content-h` rows within `container-h` rows.
sourceraw docstring

with-styleclj

(with-style g styles body-fn)

Execute body-fn (fn [g] ...) with the given styles enabled, then restore. Returns the result of body-fn.

Execute `body-fn` (fn [g] ...) with the given styles enabled, then restore.
Returns the result of `body-fn`.
sourceraw docstring

word-wrapclj

(word-wrap s width)

Greedy word-wrap s into a vec of lines, each fitting width DISPLAY columns. Breaks on whitespace; a token wider than width is hard-split at grapheme boundaries (never mid-cluster); embedded newlines are honoured. Blank input or width <= 0 yields [""].

Greedy word-wrap `s` into a vec of lines, each fitting `width` DISPLAY
columns. Breaks on whitespace; a token wider than `width` is hard-split at
grapheme boundaries (never mid-cluster); embedded newlines are honoured.
Blank input or `width` <= 0 yields `[""]`.
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