Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit3bb1da2647

README.md

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 to M.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 with is_text=false.

Types:

  • DiffLine = { op: string, text: string } — one tagged line. op is "+", "-", 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 spacetime text_blobs inline 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 via opts.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 \n doesn't produce an empty trailing element. Matches POSIX wc -l semantics and most diff tools.