▣
module · drop-in viewer
text_diff
Pure-Luau line-diff helper used by `world.diff` / `world.show` and the `zm diff` / `zm show` shell commands. LCS-based; produces structured hunks (op-tagged lines, not unified-diff text) so AI consumers can pattern-match on `op` instead of parsing `+`/`-`/` ` prefixes.
by·posted 2mo ago
What it does
text_diff
Pure-Luau line-diff helper used by world.diff / world.show and the
zm diff / zm show shell commands. LCS-based; produces structured
hunks (op-tagged lines, not unified-diff text) so AI consumers can
pattern-match on op instead of parsing +/-/ prefixes.
Exports
M.diff(oldText: string?, newText: string?, opts: DiffOpts?) -> FileDiff— diff two strings, return the structured per-file shape.M.added(newText: string?, opts: DiffOpts?) -> FileDiff— pure-add convenience (equivalent toM.diff("", newText, opts)).M.removed(oldText: string?, opts: DiffOpts?) -> FileDiff— pure-remove convenience.M.toUnifiedText(fileDiff: FileDiff) -> string— render structured diff back into unified-diff text.M.toStatLine(fileDiff: FileDiff) -> string—git diff --stat-style one-line summary.M.SIZE_CAP_BYTES: number— per-file size cap (256 KB). Files larger than this return a size-only summary withis_text=false.
Types:
DiffLine = { op: string, text: string }— one tagged line.opis"+","-", or" "(context).DiffHunk = { old_start, old_count, new_start, new_count, lines: { DiffLine } }— git-style hunk.DiffOpts = { context: number?, path: string?, action: string? }.FileDiff = { path?, action?, is_text, added?, removed?, hunks?, size_old?, size_new? }.
Usage
local TextDiff = require("@builtin::modules.text_diff")
local d = TextDiff.diff(oldBytes, newBytes, { path = "foo.luau" })
if d.is_text then
print(TextDiff.toStatLine(d)) -- "modified foo.luau +3 -1"
print(TextDiff.toUnifiedText(d))
else
print(string.format("oversize: %d -> %d bytes", d.size_old, d.size_new))
end
Notes
- The per-file size cap (
M.SIZE_CAP_BYTES = 256 * 1024) mirrors the spacetimetext_blobsinline threshold. Anything above that lives in the bucket as binary anyway, so the diff library never sees it as text in practice; the cap is belt-and-suspenders for callers that bypass the routing. - Default context window is 3 lines (matches
git diff -U3). Override viaopts.context. - Hunk header line numbers follow git's
@@ -0,0 +1,N @@shape for pure additions (and the mirror for pure deletions). - Trailing newline handling: a final
\ndoesn't produce an empty trailing element. Matches POSIXwc -lsemantics and most diff tools.
Discussion
Scoped to this part · feeds back into the world's score.
Sign in to post.sign in
No comments yet. Be the first.