Versioned line addresses: the vocabulary cat and grep print and patch spends.
A file version is the first 8 hex chars of the SHA-256 of its UTF-8 text. A read
prints the version ONCE in its header (path @3f9a1c2b) and each line as a plain
number (131│ text). patch names that version and its line numbers. When the
file changed after the read, the edit is moved through a diff from the shown
version to the current file, and refused only when its own lines changed.
split-content-lines / char-offset-at-line blob <-> line/char coordinates
content-version / parse-version text -> version, input -> version
render-numbered-block / header [[ln text]…] -> N│ text rows
remember! / recall bounded cache of shown versions
note-shown! / shown-ranges / covers? the lines that each version showed
edit-span line span -> char span
Everything is pure except the cache. The cache holds the text of each version
that a read showed, keyed by canonical path and version, so a remap can diff
from it. It drops the oldest texts above store-max-chars.
Versioned line addresses: the vocabulary `cat` and `grep` print and `patch` spends. A file version is the first 8 hex chars of the SHA-256 of its UTF-8 text. A read prints the version ONCE in its header (`path @3f9a1c2b`) and each line as a plain number (`131│ text`). `patch` names that version and its line numbers. When the file changed after the read, the edit is moved through a diff from the shown version to the current file, and refused only when its own lines changed. split-content-lines / char-offset-at-line blob <-> line/char coordinates content-version / parse-version text -> version, input -> version render-numbered-block / header [[ln text]…] -> `N│ text` rows remember! / recall bounded cache of shown versions note-shown! / shown-ranges / covers? the lines that each version showed edit-span line span -> char span Everything is pure except the cache. The cache holds the text of each version that a read showed, keyed by canonical path and version, so a remap can diff from it. It drops the oldest texts above `store-max-chars`.
(char-offset-at-line content line-idx)Char offset in content where 0-based line line-idx starts. Returns
(count content) when line-idx reaches past the last line.
Char offset in `content` where 0-based line `line-idx` starts. Returns `(count content)` when `line-idx` reaches past the last line.
(content-version content)The version-width-hex-char version of content: a prefix of its UTF-8 SHA-256.
The `version-width`-hex-char version of `content`: a prefix of its UTF-8 SHA-256.
(covers? ranges from to)Whether merged ranges hold every line of from..to.
Whether merged `ranges` hold every line of `from`..`to`.
(edit-span content from-line to-line replacement)The CHAR SPAN that replaces lines from-line..to-line (1-based, inclusive) of
content with replacement: {:start S :end E :replacement R :from-line N :to-line N}.
The caller checks the range.
Newline semantics: a replacement need NOT end in \n — the matched region's
terminator is preserved (\r\n stays \r\n on a CRLF file) — and one that
DOES is not doubled: exactly one trailing terminator is dropped. An EMPTY
replacement consumes the trailing newline, so the lines actually vanish.
The CHAR SPAN that replaces lines `from-line`..`to-line` (1-based, inclusive) of
`content` with `replacement`: `{:start S :end E :replacement R :from-line N :to-line N}`.
The caller checks the range.
Newline semantics: a replacement need NOT end in `\n` — the matched region's
terminator is preserved (`\r\n` stays `\r\n` on a CRLF file) — and one that
DOES is not doubled: exactly one trailing terminator is dropped. An EMPTY
replacement consumes the trailing newline, so the lines actually vanish.(forget-all!)Empty the caches. Tests use it to model a version that the host no longer knows.
Empty the caches. Tests use it to model a version that the host no longer knows.
Separator between the line number and the line text in every rendered row.
U+2502 plus a space: it never occurs in source, so line.split("│ ", 1) is exact.
Separator between the line number and the line text in every rendered row.
U+2502 plus a space: it never occurs in source, so `line.split("│ ", 1)` is exact.(header rel version)The header line of a read: the path and its version.
The header line of a read: the path and its version.
(note-shown! path version ranges)Record that a cat, grep or patch result showed ranges (inclusive [from to]
line pairs) of version of the file at canonical path. The record is for the
whole process, like the text cache.
Record that a `cat`, `grep` or `patch` result showed `ranges` (inclusive `[from to]` line pairs) of `version` of the file at canonical `path`. The record is for the whole process, like the text cache.
(parse-version x)The bare version in x, which may carry the header's leading @, or nil.
The bare version in `x`, which may carry the header's leading `@`, or nil.
(recall path version)The cached text of version of the file at canonical path, or nil.
The cached text of `version` of the file at canonical `path`, or nil.
(remember! path content)Cache content as a shown version of the file at canonical path. Answers its version.
Cache `content` as a shown version of the file at canonical `path`. Answers its version.
(render-numbered-block tuples)(render-numbered-block tuples indent)Render [[line-number text] …] as N│ text rows, each prefixed by indent.
A CRLF line renders without its CR: the text a reader copies back must not
carry a second line ending.
Render `[[line-number text] …]` as `N│ text` rows, each prefixed by `indent`. A CRLF line renders without its CR: the text a reader copies back must not carry a second line ending.
(shown-ranges path version)The merged line ranges that results showed of version of the file at canonical
path, or nil when no result recorded one.
The merged line ranges that results showed of `version` of the file at canonical `path`, or nil when no result recorded one.
(split-content-lines s)Split a file blob into a vec of lines. A trailing empty element (from the file's final newline) is dropped, so the vector's count IS the file's line count and index 0 is line 1.
Split a file blob into a vec of lines. A trailing empty element (from the file's final newline) is dropped, so the vector's count IS the file's line count and index 0 is line 1.
Hex chars in a file version. 32 bits make an accidental match between two texts of one file negligible, and the version appears once per file, not per line.
Hex chars in a file version. 32 bits make an accidental match between two texts of one file negligible, and the version appears once per file, not per line.
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 |