Keyboard / paste / clipboard surface for the TUI channel.
Clipboard read/write goes through OS shell helpers only: pbcopy /
pbpaste on macOS (always present since 10.0), wl-copy /
wl-paste on Wayland, xclip / xsel on X11.
Keyboard / paste / clipboard surface for the TUI channel. Clipboard read/write goes through OS shell helpers only: `pbcopy` / `pbpaste` on macOS (always present since 10.0), `wl-copy` / `wl-paste` on Wayland, `xclip` / `xsel` on X11.
Lanterna's stock Alt+character decoder rejects ISO control chars. Option+Backspace commonly arrives as ESC + DEL (0x7f), with some terminals using ESC + Ctrl-H (0x08). Surface both as Alt+Backspace so the editor can delete one word backward.
Lanterna's stock Alt+character decoder rejects ISO control chars. Option+Backspace commonly arrives as ESC + DEL (0x7f), with some terminals using ESC + Ctrl-H (0x08). Surface both as Alt+Backspace so the editor can delete one word backward.
(alt-char? key c)True for Alt/Option + character c, case-insensitive.
True for Alt/Option + character `c`, case-insensitive.
(alt-modifier? key)True when Lanterna decoded an Alt/Option modifier.
True when Lanterna decoded an Alt/Option modifier.
(bare-escape? k)True for a plain Escape KeyStroke (not a MouseAction).
True for a plain Escape KeyStroke (not a MouseAction).
(clipboard-copy! text)Best-effort copy text onto the system clipboard via shell
helpers (pbcopy / wl-copy / xclip / xsel). Returns true
on success, false when every helper failed. Logs the winning
helper so "the copy didn't work" reports can be diagnosed
against ~/.vis/vis.log.
Best-effort copy `text` onto the system clipboard via shell helpers (`pbcopy` / `wl-copy` / `xclip` / `xsel`). Returns true on success, false when every helper failed. Logs the winning helper so "the copy didn't work" reports can be diagnosed against `~/.vis/vis.log`.
(clipboard-paste)Read the system clipboard as a UTF-8 string. Returns the captured
text or nil when no helper produced output.
Read the system clipboard as a UTF-8 string. Returns the captured text or `nil` when no helper produced output.
(collapse-paste-placeholders text pastes-map)Substitute every [Pasted #N: ...] token in text with a fenced
vis-paste block the TUI renders as a COLLAPSIBLE disclosure: the
[Pasted #N: ...] token becomes the chevron summary row, the full
payload the body you expand to read. Used by the send path to build
the VISIBLE transcript copy — the user keeps a one-line marker they
can open on demand, while expand-paste-placeholders still ships the
complete payload to the agent.
The block body is <token>\n<full content>: the renderer peels the
first line off as the summary and shows the rest verbatim when
expanded (no head+tail truncation — the whole paste survives a
session reopen). A four-backtick fence keeps ordinary three-backtick
code the payload may itself contain from closing it early. Tokens
with no entry in pastes-map pass through unchanged.
Substitute every `[Pasted #N: ...]` token in `text` with a fenced `vis-paste` block the TUI renders as a COLLAPSIBLE disclosure: the `[Pasted #N: ...]` token becomes the chevron summary row, the full payload the body you expand to read. Used by the send path to build the VISIBLE transcript copy — the user keeps a one-line marker they can open on demand, while `expand-paste-placeholders` still ships the complete payload to the agent. The block body is `<token>\n<full content>`: the renderer peels the first line off as the summary and shows the rest verbatim when expanded (no head+tail truncation — the whole paste survives a session reopen). A four-backtick fence keeps ordinary three-backtick code the payload may itself contain from closing it early. Tokens with no entry in `pastes-map` pass through unchanged.
(ctrl-char? key c)True for Ctrl + character c, case-insensitive. The reliable, cross-platform
modifier for in-modal toggles (Alt/Option is eaten by stock macOS terminals).
Pick c to avoid the terminal control codes (I=Tab, M=Enter, H=BS, S/Q=flow
control, O=stty DISCARD), which never arrive as a Character keystroke.
True for Ctrl + character `c`, case-insensitive. The reliable, cross-platform modifier for in-modal toggles (Alt/Option is eaten by stock macOS terminals). Pick `c` to avoid the terminal control codes (I=Tab, M=Enter, H=BS, S/Q=flow control, O=stty DISCARD), which never arrive as a Character keystroke.
Make Ctrl+H reach the app as Ctrl+H. The terminal sends byte 0x08 for Ctrl+H,
which lanterna's DEFAULT profile decodes as Backspace — so help-on-Ctrl+H was
dead (it just deleted a char). Decode a LONE 0x08 as Ctrl+H instead (char h
InputDecoder.getBestMatch keeps
the LAST full match, so this wins over the stock 0x08->Backspace mapping.
(Option+Backspace = ESC+0x08 is a TWO-char sequence handled by
alt-backspace-pattern, so it does not collide with this lone-0x08 match.)Make Ctrl+H reach the app as Ctrl+H. The terminal sends byte 0x08 for Ctrl+H, which lanterna's DEFAULT profile decodes as Backspace — so help-on-Ctrl+H was dead (it just deleted a char). Decode a LONE 0x08 as Ctrl+H instead (char `h` + ctrl). The physical Backspace key sends 0x7f on every modern terminal (macOS Terminal/iTerm2, Linux), so it stays Backspace and is unaffected. Registered AFTER the default profile, and `InputDecoder.getBestMatch` keeps the LAST full match, so this wins over the stock 0x08->Backspace mapping. (Option+Backspace = ESC+0x08 is a TWO-char sequence handled by `alt-backspace-pattern`, so it does not collide with this lone-0x08 match.)
(ctrl-modifier? key)True when Lanterna decoded a Ctrl modifier.
True when Lanterna decoded a Ctrl modifier.
(delete-placeholder-backward {:keys [lines crow ccol] :as state})Remove the placeholder token immediately before the cursor in
state. Returns the new state (whole token gone, cursor at the
start of where the token was). Caller is responsible for dropping
the matching :pastes entry from app-db.
No-op when no placeholder ends at the cursor - the screen loop
guards via placeholder-id-before-cursor first.
Remove the placeholder token immediately before the cursor in `state`. Returns the new state (whole token gone, cursor at the start of where the token was). Caller is responsible for dropping the matching `:pastes` entry from app-db. No-op when no placeholder ends at the cursor - the screen loop guards via `placeholder-id-before-cursor` first.
(disable-bracketed-paste! out)Reverse of enable-bracketed-paste!. Always called in the screen
tear-down finally so a crashed TUI doesn't leave the user's
shell stuck in bracketed-paste mode.
Reverse of `enable-bracketed-paste!`. Always called in the screen tear-down `finally` so a crashed TUI doesn't leave the user's shell stuck in bracketed-paste mode.
(disable-literal-next!)Disable the tty's IEXTEN so Ctrl+V (VLNEXT — the line discipline's "literal
next" quoting char) and Ctrl+O (VDISCARD) reach the app as real keystrokes
instead of being swallowed before lanterna ever decodes them. This is the SAME
raw-mode move Emacs (and every terminal Emacs) makes so C-v can scroll. Best
effort; a host without stty simply keeps Ctrl+V as literal-next. Paired with
restore-literal-next! on teardown.
Disable the tty's IEXTEN so Ctrl+V (VLNEXT — the line discipline's "literal next" quoting char) and Ctrl+O (VDISCARD) reach the app as real keystrokes instead of being swallowed before lanterna ever decodes them. This is the SAME raw-mode move Emacs (and every terminal Emacs) makes so `C-v` can scroll. Best effort; a host without stty simply keeps Ctrl+V as literal-next. Paired with `restore-literal-next!` on teardown.
(disable-sgr-mouse! out)Reverse of enable-sgr-mouse!. Sent in the screen tear-down
finally so a crashed TUI doesn't leave the user's shell with
the mode dangling.
Reverse of `enable-sgr-mouse!`. Sent in the screen tear-down `finally` so a crashed TUI doesn't leave the user's shell with the mode dangling.
(drain-sgr-leak! poll-next)Swallow a literal SGR mouse tail that leaked past the decoder.
When the bytes of an SGR mouse report split across two terminal reads
(wheel flood, GC/paint hitch, tmux/SSH chunking), Lanterna's decoder
sees only the lone ESC, emits the bare-Escape full match, and the rest
of the sequence - [<65;32;43M or <65;32;43M - decodes as ordinary
Character keystrokes that would be typed into the input box. Call this
right after a bare Escape keystroke with a NON-BLOCKING poll-next:
it consumes queued Character keystrokes while they spell
[? < digits ; digits ; digits M|m runs (back-to-back runs included).
Returns {:swallowed? <true when at least one complete run was dropped>
:replay [consumed keystrokes that were NOT part of a run]}.
The caller must replay :replay (oldest first) as if never consumed.
Real typing is unaffected: a human cannot queue a '<' in the same
millisecond burst as an Escape press, and an incomplete candidate is
replayed verbatim.
Swallow a literal SGR mouse tail that leaked past the decoder.
When the bytes of an SGR mouse report split across two terminal reads
(wheel flood, GC/paint hitch, tmux/SSH chunking), Lanterna's decoder
sees only the lone ESC, emits the bare-Escape full match, and the rest
of the sequence - `[<65;32;43M` or `<65;32;43M` - decodes as ordinary
Character keystrokes that would be typed into the input box. Call this
right after a bare Escape keystroke with a NON-BLOCKING `poll-next`:
it consumes queued Character keystrokes while they spell
`[? < digits ; digits ; digits M|m` runs (back-to-back runs included).
Returns {:swallowed? <true when at least one complete run was dropped>
:replay [consumed keystrokes that were NOT part of a run]}.
The caller must replay `:replay` (oldest first) as if never consumed.
Real typing is unaffected: a human cannot queue a '<' in the same
millisecond burst as an Escape press, and an incomplete candidate is
replayed verbatim.(enable-bracketed-paste! out)Tell the terminal to wrap subsequent pastes in ESC[200~ ... ESC[201~.
Bytes go straight to the controlling TTY; safe to call inside the
screen lifecycle.
Tell the terminal to wrap subsequent pastes in `ESC[200~ ... ESC[201~`. Bytes go straight to the controlling TTY; safe to call inside the screen lifecycle.
(enable-sgr-mouse! out)Send ESC [ ? 1006 h. Asks the terminal to deliver subsequent
mouse events in SGR encoding. Independent of the legacy
mode-1003 enable Lanterna already issues via
setMouseCaptureMode; both can be active at once and the
terminal will use whichever the remote consumer claims to
support - every modern emulator (Apple Terminal 2.10+, iTerm2,
alacritty, kitty, wezterm, foot, gnome-terminal, mintty,
vscode integrated terminal) honours 1006.
Send `ESC [ ? 1006 h`. Asks the terminal to deliver subsequent mouse events in SGR encoding. Independent of the legacy mode-1003 enable Lanterna already issues via `setMouseCaptureMode`; both can be active at once and the terminal will use whichever the remote consumer claims to support - every modern emulator (Apple Terminal 2.10+, iTerm2, alacritty, kitty, wezterm, foot, gnome-terminal, mintty, vscode integrated terminal) honours 1006.
Full match for bare Escape. Custom ESC-prefixed patterns below return partial matches for Alt+Enter, Alt+Backspace, bracketed paste, and SGR mouse sequences. Lanterna keeps a candidate full match only when one exists; without this, a lone Esc can stay buffered and the next Enter is decoded as Alt+Enter instead of closing/canceling.
Full match for bare Escape. Custom ESC-prefixed patterns below return partial matches for Alt+Enter, Alt+Backspace, bracketed paste, and SGR mouse sequences. Lanterna keeps a candidate full match only when one exists; without this, a lone Esc can stay buffered and the next Enter is decoded as Alt+Enter instead of closing/canceling.
(expand-file-mentions text)Replace inline @path/to/file mentions with a short read-this-file
directive aimed at the agent.
The visible chat transcript keeps the concise @path token (the
:send-message event passes the un-expanded text as the display
value, so the user bubble and persisted user_request stay short).
The outbound agent prompt - this function's output - carries the
directive so the model knows the user attached the file and should
read it before answering. We deliberately do NOT inject any
(def ...) / (cat ...) / (cat ...) boilerplate; forcing
a specific first-observation form makes the model dump focused-range
previews even when the question is structural and wastes iterations.
Unknown paths pass through unchanged.
Replace inline `@path/to/file` mentions with a short read-this-file directive aimed at the agent. The visible chat transcript keeps the concise `@path` token (the `:send-message` event passes the un-expanded text as the display value, so the user bubble and persisted `user_request` stay short). The outbound agent prompt - this function's output - carries the directive so the model knows the user attached the file and should read it before answering. We deliberately do NOT inject any `(def ...)` / `(cat ...)` / `(cat ...)` boilerplate; forcing a specific first-observation form makes the model dump focused-range previews even when the question is structural and wastes iterations. Unknown paths pass through unchanged.
(expand-paste-placeholders text pastes-map)Substitute every [Pasted #N: ...] token in text with its content
from pastes-map. Used by the send path so the agent receives
the user's full payload, not the cosmetic token.
pastes-map shape: {<id-int> {:id N :content "..."}}.
Tokens whose id has no entry in the map (e.g. the user typed the
bracket text manually) pass through unchanged.
NOTE: clojure.string/replace with a fn already runs the fn's
return through Matcher/quoteReplacement internally, so a
payload carrying $ or \ is handled verbatim - we don't
double-quote here.
Substitute every `[Pasted #N: ...]` token in `text` with its content
from `pastes-map`. Used by the send path so the agent receives
the user's full payload, not the cosmetic token.
`pastes-map` shape: `{<id-int> {:id N :content "..."}}`.
Tokens whose id has no entry in the map (e.g. the user typed the
bracket text manually) pass through unchanged.
NOTE: `clojure.string/replace` with a fn already runs the fn's
return through `Matcher/quoteReplacement` internally, so a
payload carrying `$` or `\` is handled verbatim - we don't
double-quote here.(format-file-mention path)Visible inline file mention token inserted by the @ picker.
Paths containing whitespace are quoted so send-time expansion can
still recover the exact filename.
Visible inline file mention token inserted by the `@` picker. Paths containing whitespace are quoted so send-time expansion can still recover the exact filename.
(format-paste-placeholder {:keys [id content image]})Produce the visible token text for app-db :pastes entry entry.
Pure: same input -> same output, no allocation games. Used both
when the screen loop inserts the token AND when the renderer or
send path needs to re-derive the canonical shape.
Always carries BOTH the line count AND the human-readable byte weight - the user wants to see both at a glance:
[Pasted #1: 42 lines, 1.2KB] [Pasted #2: 1 line, 73B]
lines is correctly pluralised; size is locale-safe via
format-bytes so a Polish JVM doesn't render 1,2KB.
Produce the visible token text for `app-db :pastes` entry `entry`. Pure: same input -> same output, no allocation games. Used both when the screen loop inserts the token AND when the renderer or send path needs to re-derive the canonical shape. Always carries BOTH the line count AND the human-readable byte weight - the user wants to see both at a glance: [Pasted #1: 42 lines, 1.2KB] [Pasted #2: 1 line, 73B] `lines` is correctly pluralised; size is locale-safe via `format-bytes` so a Polish JVM doesn't render `1,2KB`.
(handle-key key state)Process keystroke. Returns {:action kw, :state s}.
Process keystroke. Returns {:action kw, :state s}.
(input-empty? state)True when the input buffer is the pristine empty prompt.
Whitespace, extra lines, or cursor state from edits count as non-empty so Esc/Ctrl+C can clear the draft before they regain their quit/cancel meaning.
True when the input buffer is the pristine empty prompt. Whitespace, extra lines, or cursor state from edits count as non-empty so Esc/Ctrl+C can clear the draft before they regain their quit/cancel meaning.
(keystroke->paste-char key)Convert one KeyStroke received WHILE INSIDE a bracketed-paste block into the character it represents, so the buffer reflects the user's pasted bytes verbatim. Returns nil for keystrokes that don't map to a single text character (e.g. function keys); the input loop drops those.
Convert one KeyStroke received WHILE INSIDE a bracketed-paste block into the character it represents, so the buffer reflects the user's pasted bytes verbatim. Returns nil for keystrokes that don't map to a single text character (e.g. function keys); the input loop drops those.
Decode xterm-style modified arrows (ESC[1;<mod>A-D) into Lanterna
KeyStrokes with Ctrl/Alt/Shift flags. macOS/iTerm/Terminal commonly
use these for Option/Shift arrow combos; Lanterna's stock decoder does
not consistently surface Alt+arrow across terminals.
Decode xterm-style modified arrows (`ESC[1;<mod>A-D`) into Lanterna KeyStrokes with Ctrl/Alt/Shift flags. macOS/iTerm/Terminal commonly use these for Option/Shift arrow combos; Lanterna's stock decoder does not consistently surface Alt+arrow across terminals.
(paste-content-preview content)Head+tail preview lines for a pasted payload. Short payloads come back
whole (each line clamped); long ones keep the first
PASTE_PREVIEW_HEAD_LINES and last PASTE_PREVIEW_TAIL_LINES lines with
a ⋯ N more lines ⋯ marker between them. Returns a seq of strings.
Head+tail preview lines for a pasted payload. Short payloads come back whole (each line clamped); long ones keep the first `PASTE_PREVIEW_HEAD_LINES` and last `PASTE_PREVIEW_TAIL_LINES` lines with a `⋯ N more lines ⋯` marker between them. Returns a seq of strings.
(paste-marker? key marker)True when key is the bracketed-paste START or END marker. Lets
the screen polling loop pick the brackets out before normal key
handling runs.
True when `key` is the bracketed-paste START or END marker. Lets the screen polling loop pick the brackets out before normal key handling runs.
PUA marker char for the bracketed-paste END sequence (ESC[201~).
PUA marker char for the bracketed-paste END sequence (`ESC[201~`).
Threshold below which we DON'T use a placeholder - a short
single-line paste like git rev-parse HEAD reads naturally
inline and a placeholder would just be noise.
Threshold below which we DON'T use a placeholder - a short single-line paste like `git rev-parse HEAD` reads naturally inline and a placeholder would just be noise.
How many leading lines of a pasted payload the collapsed transcript preview shows.
How many leading lines of a pasted payload the collapsed transcript preview shows.
A single previewed line longer than this is itself middle-elided so one 2KB single-line paste can't blow the bubble open.
A single previewed line longer than this is itself middle-elided so one 2KB single-line paste can't blow the bubble open.
How many trailing lines of a pasted payload the collapsed transcript preview shows.
How many trailing lines of a pasted payload the collapsed transcript preview shows.
PUA marker char used as the KeyStroke payload when the bracketed-
paste START sequence (ESC[200~) arrives. Picked from the same
PUA range our inline-style sentinels live in (U+E2xx) so a stray
bracket lookalike in real text could never collide with it.
PUA marker char used as the KeyStroke payload when the bracketed- paste START sequence (`ESC[200~`) arrives. Picked from the same PUA range our inline-style sentinels live in (U+E2xx) so a stray bracket lookalike in real text could never collide with it.
(placeholder-id-before-cursor {:keys [lines crow ccol]})When the cursor of state sits IMMEDIATELY AFTER the closing ]
of a paste placeholder on the current line, return that
placeholder's :id (Integer). nil otherwise. The screen loop
uses this to turn one Backspace into a whole-token delete.
When the cursor of `state` sits IMMEDIATELY AFTER the closing `]` of a paste placeholder on the current line, return that placeholder's `:id` (Integer). nil otherwise. The screen loop uses this to turn one Backspace into a whole-token delete.
Anchored shape [Pasted #N: ...] / [Image #N: ...]. The non-greedy
negated-bracket body keeps the regex idempotent against nested-bracket
text the user may have typed adjacent to the placeholder. Group 1 is
always the numeric id — the leading kind word is non-capturing.
Anchored shape `[Pasted #N: ...]` / `[Image #N: ...]`. The non-greedy negated-bracket body keeps the regex idempotent against nested-bracket text the user may have typed adjacent to the placeholder. Group 1 is always the numeric id — the leading kind word is non-capturing.
(read-clipboard-image!)Best-effort read of an IMAGE sitting on the system clipboard. Writes it to a
temp PNG file and returns {:path :mime} (mime always "image/png"), or
nil when the clipboard holds no image / no helper is available. Lets ⌘V of a
screenshot or a copied image attach the pixels, matching the web channel's
paste behaviour. Never throws.
Best-effort read of an IMAGE sitting on the system clipboard. Writes it to a
temp PNG file and returns `{:path :mime}` (mime always `"image/png"`), or
nil when the clipboard holds no image / no helper is available. Lets ⌘V of a
screenshot or a copied image attach the pixels, matching the web channel's
paste behaviour. Never throws.(register-custom-patterns! terminal)Register Escape, Alt+Enter, Alt+Backspace, modified arrows,
bracketed-paste, and SGR-mouse patterns on the terminal's input
decoder. Without sgr-mouse-pattern the stock Lanterna parser
handles only legacy X10 mouse events, whose raw-byte coordinate
encoding clashes with the JVM's UTF-8 input decoder for any
column/row beyond 95 - producing a phantom mx=65500 from a U+FFFD
replacement byte.
Register Escape, Alt+Enter, Alt+Backspace, modified arrows, bracketed-paste, and SGR-mouse patterns on the terminal's input decoder. Without `sgr-mouse-pattern` the stock Lanterna parser handles only legacy X10 mouse events, whose raw-byte coordinate encoding clashes with the JVM's UTF-8 input decoder for any column/row beyond 95 - producing a phantom `mx=65500` from a U+FFFD replacement byte.
Hint label for the list-reorder keys. Plain K/J always reach the app
(Shift/Alt+↑/↓ also work where the terminal sends the xterm sequence).
Hint label for the list-reorder keys. Plain `K`/`J` always reach the app (Shift/Alt+↑/↓ also work where the terminal sends the xterm sequence).
(reorder-modifier? key)True when a MODIFIED arrow should reorder a list item instead of moving the
cursor. Shift/Alt+↑/↓ is a BONUS path (decoded from the xterm modified-arrow
sequence); the reliable, documented reorder keys are plain K/J, handled
directly in each list dialog — stock macOS terminals don't surface
Alt+arrow, and Option+arrow is reserved for word motion.
True when a MODIFIED arrow should reorder a list item instead of moving the cursor. Shift/Alt+↑/↓ is a BONUS path (decoded from the xterm modified-arrow sequence); the reliable, documented reorder keys are plain `K`/`J`, handled directly in each list dialog — stock macOS terminals don't surface Alt+arrow, and Option+arrow is reserved for word motion.
(reset-default-bg! out)Reverse of set-default-bg! via OSC 111 (reset default background).
Always called in the screen tear-down finally so the user's shell
gets its original background back.
Reverse of `set-default-bg!` via OSC 111 (reset default background). Always called in the screen tear-down `finally` so the user's shell gets its original background back.
(restore-literal-next!)Re-enable IEXTEN on teardown so the user's shell gets its literal-next / discard quoting back, regardless of whether lanterna restores termios itself.
Re-enable IEXTEN on teardown so the user's shell gets its literal-next / discard quoting back, regardless of whether lanterna restores termios itself.
(set-default-bg! out r g b)Set the terminal's DEFAULT background color via OSC 11. Modern emulators (iTerm2, kitty, ghostty, wezterm, alacritty, foot, vscode) extend the default background into the window padding around the cell grid - without this the padding stays the user's shell color (often white) instead of the theme background. Best-effort: a terminal that ignores OSC 11 simply keeps its own background.
Set the terminal's DEFAULT background color via OSC 11. Modern emulators (iTerm2, kitty, ghostty, wezterm, alacritty, foot, vscode) extend the default background into the window padding around the cell grid - without this the padding stays the user's shell color (often white) instead of the theme background. Best-effort: a terminal that ignores OSC 11 simply keeps its own background.
CharacterPattern matching ESC [ < N ; N ; N M/m. Emits a
MouseAction with proper integer column/row so SGR-capable
terminals (every modern macOS / Linux emulator) deliver clicks
that the screen handler can hit-test against click regions.
Returns NOT_YET while the prefix is still consistent with the
shape, returns nil (no match) the instant a character violates
it, returns Matching with the built MouseAction once the final
M / m byte arrives.
CharacterPattern matching `ESC [ < N ; N ; N M/m`. Emits a `MouseAction` with proper integer column/row so SGR-capable terminals (every modern macOS / Linux emulator) deliver clicks that the screen handler can hit-test against click regions. Returns NOT_YET while the prefix is still consistent with the shape, returns nil (no match) the instant a character violates it, returns Matching with the built MouseAction once the final `M` / `m` byte arrives.
(shift-modifier? key)True when Lanterna decoded a Shift modifier.
True when Lanterna decoded a Shift modifier.
(use-placeholder? text)True when the pasted text is large enough OR multi-line enough
that the user benefits from the placeholder UX. Single-line
ASCII pastes shorter than PASTE_INLINE_MAX_CHARS go inline.
True when the pasted text is large enough OR multi-line enough that the user benefits from the placeholder UX. Single-line ASCII pastes shorter than `PASTE_INLINE_MAX_CHARS` go inline.
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 |