Liking cljdoc? Tell your friends :D

com.blockether.vis.internal.foundation.editing.zipper

Language-neutral STRUCTURAL ZIPPER over the tree-sitter pack (306+ langs) — the unified cursor the name-based structural ops were missing.

A node's location is a STATELESS PATH: a vector of NAMED-child indices from the root (e.g. [2 0] = first named child of the third named child of the file). Stateless means it round-trips cleanly through async tool calls — no live native cursor to keep between calls. Relative moves (down/up/next/prev) are pure path arithmetic on top, so the model navigates like a rewrite-clj zipper but over EVERY language tree-sitter understands.

Edits splice the target node's UTF-8 byte range and RE-PARSE, refusing a result that introduces a syntax error the original didn't have — the same safety contract as structural. Pairs with the name-based ops: locate a def by name, then walk into it by path.

All native handles (Parser/Tree/Node) are opened and closed inside each call; only plain Clojure data escapes.

Language-neutral STRUCTURAL ZIPPER over the tree-sitter pack (306+ langs) —
the unified cursor the name-based `structural` ops were missing.

A node's location is a STATELESS PATH: a vector of NAMED-child indices from
the root (e.g. `[2 0]` = first named child of the third named child of the
file). Stateless means it round-trips cleanly through async tool calls — no
live native cursor to keep between calls. Relative moves (down/up/next/prev)
are pure path arithmetic on top, so the model navigates like a rewrite-clj
zipper but over EVERY language tree-sitter understands.

Edits splice the target node's UTF-8 byte range and RE-PARSE, refusing a
result that introduces a syntax error the original didn't have — the same
safety contract as `structural`. Pairs with the name-based ops: locate a def
by name, then walk into it by path.

All native handles (Parser/Tree/Node) are opened and closed inside each call;
only plain Clojure data escapes.
raw docstring

describe-syntax-errorsclj

(describe-syntax-errors lang source)

Model-actionable, MULTI-LINE report of the ERROR/MISSING nodes in source (parsed as lang), or nil when it parses clean. Names WHERE the parser broke, SHOWS those lines with a caret, names WHICH delimiter tree-sitter expected when it knows, and closes with a language-appropriate cause — so a rejected edit never degenerates into blind paren-counting.

Model-actionable, MULTI-LINE report of the ERROR/MISSING nodes in `source`
(parsed as `lang`), or nil when it parses clean. Names WHERE the parser broke,
SHOWS those lines with a caret, names WHICH delimiter tree-sitter expected when
it knows, and closes with a language-appropriate cause — so a rejected edit
never degenerates into blind paren-counting.
sourceraw docstring

detect-languageclj

(detect-language path)
source

editclj

(edit lang source at op code)

Splice the node at at. op ∈ #{:replace :insert-before :insert-after :append-child :prepend-child} with code (clojure.zip vocabulary). RE-PARSES and refuses a result that introduces a syntax error the original file didn't have. Returns {:ok? true :new-source S} or {:error …}. :append-child / :prepend-child insert after the LAST / before the FIRST named child of the node at at. Insert-before/after reuse the file's inter-sibling gap so a spliced form keeps the blank-line rhythm; delete (= :replace with "") reclaims one adjacent gap so the survivors keep a single separator, not an orphaned blank line.

Splice the node at `at`. `op` ∈ #{:replace :insert-before :insert-after
:append-child :prepend-child} with `code` (clojure.zip vocabulary). RE-PARSES
and refuses a result that introduces a syntax error the original file didn't
have. Returns `{:ok? true :new-source S}` or `{:error …}`.
:append-child / :prepend-child insert after the LAST / before the FIRST named
child of the node at `at`. Insert-before/after reuse the file's inter-sibling gap so
a spliced form keeps the blank-line rhythm; delete (= :replace with "") reclaims one
adjacent gap so the survivors keep a single separator, not an orphaned blank line.
sourceraw docstring

error-nodesclj

(error-nodes lang source)

Every ERROR / MISSING node tree-sitter finds in source (parsed as lang), as [{:line :col :byte-col :end-line :end-col :start-byte :end-byte :kind :missing? :text} …] in document order (1-based line, 0-based Unicode code-point col; :byte-col preserves tree-sitter's raw UTF-8 column). Empty when the source parses clean or the language can't be parsed. Public so an edit guard can turn a bare "N syntax error(s)" rejection into a LOCATED, actionable message — a MISSING node even NAMES the delimiter the parser expected (:kind = ], ), …).

An ERROR node reports the most actionable UNBALANCED DELIMITER directly inside it, not necessarily the node's own start: an unclosed form can make tree-sitter open one ERROR over the whole file whose start is line 1. Those rows carry :delimiter and :error-line (where recovery began), and :text is the offending LINE. Raw byte spans remain available so a diagnostic can recognize and look through a broad recovery wrapper that contains a more specific ERROR.

Every ERROR / MISSING node tree-sitter finds in `source` (parsed as `lang`),
as [{:line :col :byte-col :end-line :end-col :start-byte :end-byte :kind
:missing? :text} …] in document order (1-based line, 0-based Unicode
code-point col; `:byte-col` preserves tree-sitter's raw UTF-8 column). Empty
when the source parses clean or the language can't be parsed. Public so an
edit guard can turn a bare "N syntax error(s)" rejection into a LOCATED,
actionable message — a MISSING node even NAMES the delimiter the parser
expected (`:kind` = `]`, `)`, …).

An ERROR node reports the most actionable UNBALANCED DELIMITER directly inside
it, not necessarily the node's own start: an unclosed form can make tree-sitter
open one ERROR over the whole file whose start is line 1. Those rows carry
`:delimiter` and `:error-line` (where recovery began), and `:text` is the
offending LINE. Raw byte spans remain available so a diagnostic can recognize
and look through a broad recovery wrapper that contains a more specific ERROR.
sourceraw docstring

inspectclj

(inspect lang source at)

Structural view of the node at at (vector of named-child indices) in source (language lang): its kind, line span, text, s-expression, and a pick-list of immediate named children with indices. at = [] is the file root. Pure data.

Structural view of the node at `at` (vector of named-child indices) in
`source` (language `lang`): its kind, line span, text, s-expression, and a
pick-list of immediate named children with indices. `at = []` is the file
root. Pure data.
sourceraw docstring

moves-availableclj

(moves-available lang source path)

Which cursor moves are possible from path, so the model sees its options instead of probing — down (HAS named children), up, left / right (a sibling exists), next / prev (depth-first) — plus its index among siblings and the sibling count (so lefts = index, rights = siblings-1-index).

Which cursor moves are possible from `path`, so the model sees its options
instead of probing — down (HAS named children), up, left / right (a sibling
exists), next / prev (depth-first) — plus its `index` among siblings and the
sibling count (so `lefts` = index, `rights` = siblings-1-index).
sourceraw docstring

(navigate lang source at moves)

Resolve at (a named-child index path) + a sequence of relative moves against the ACTUAL tree → {:ok? true :path [...]} or {:error …}. The full clojure.zip / rewrite-clj cursor vocabulary (single-letter aliases): sibling/parent/child : up|u|t down|d|b left|l right|r leftmost|first rightmost|last root|home {child: i} depth-first : next|n prev|p search (rewrite-clj) : {find: "text"} {find_kind: "if_statement"} Boundary / not-found moves FAIL CLOSED instead of silently going nowhere.

Resolve `at` (a named-child index path) + a sequence of relative `moves`
against the ACTUAL tree → {:ok? true :path [...]} or {:error …}. The full
clojure.zip / rewrite-clj cursor vocabulary (single-letter aliases):
  sibling/parent/child : up|u|t  down|d|b  left|l  right|r  leftmost|first
                         rightmost|last  root|home  {child: i}
  depth-first          : next|n  prev|p
  search (rewrite-clj) : {find: "text"}   {find_kind: "if_statement"}
Boundary / not-found moves FAIL CLOSED instead of silently going nowhere.
sourceraw docstring

path-at-anchorclj

(path-at-anchor lang source anchor)

Resolve a lineno:hash anchor (a struct_index / cat row's SOLE position) to a named-child index PATH — the zipper entry point for that row. The hash is verified against source with the SAME machinery patch uses (patch/resolve-anchor-range): a stale / misplaced anchor is refused, not silently mis-resolved. On success the OUTERMOST named node beginning on the anchored line is located. Returns {:ok? true :path [...] :line L} or {:error {:reason KW :message S}}. Language-neutral (every tree-sitter lang).

Resolve a `lineno:hash` `anchor` (a struct_index / cat row's SOLE
position) to a named-child index PATH — the zipper entry point for that row.
The hash is verified against `source` with the SAME machinery `patch` uses
(`patch/resolve-anchor-range`): a stale / misplaced anchor is refused, not
silently mis-resolved. On success the OUTERMOST named node beginning on the
anchored line is located. Returns `{:ok? true :path [...] :line L}` or
`{:error {:reason KW :message S}}`. Language-neutral (every tree-sitter lang).
sourceraw docstring

syntax-broken?clj

(syntax-broken? lang source)

True when source parses to a tree whose root carries an ERROR node (nil when the language can't be parsed at all — fail-open, so callers never block on an unparseable input). Public so patch can re-parse its result and refuse a syntax-breaking edit, the same guard struct_patch/struct_rename already run.

True when `source` parses to a tree whose root carries an ERROR node (nil when
the language can't be parsed at all — fail-open, so callers never block on an
unparseable input). Public so `patch` can re-parse its result and refuse a
syntax-breaking edit, the same guard `struct_patch`/`struct_rename` already run.
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