#!/usr/bin/env txr @(do (set *stdout* (open-file "errors.err" "w"))) @(repeat) @ (some) +++ @dir/@path @; Don't include deleted files: editor can't open them. @ (require (nequal `@dir/@path` "/dev/null")) @ (or) +++ @path@\t@nil @ (end) @ (repeat) @@@@ -@line0,@len0 +@line1,@len1 @@@@@(skip) @ (bind (line start minuses pluses old) (0 nil 0 0 nil)) @ (set line1 @(toint line1)) @ (repeat) @ (cases) -@text @ (do (inc minuses) (set start line) (push text old)) @ (or) @ (some) @/[^+\-]/@nil @ (or) +@nil @; Tricky! This (do ...) is performed for every + line ... @ (do (if (eql 1 (inc pluses)) (set start line)) (inc line)) @; But then due to the following @(eof) the match fails if the + is @; not the last line, causing the output-generating @(do) below to @; be skipped. The idea is to perform the below output section @; even for a + line, if that line is the last line of diff output, @; when the last hunk adds files to the end of the file. @ (eof) @ (end) @ (do (inc line) (when start (let ((wording (cond ((zerop minuses) `@pluses lines added`) ((zerop pluses) `@minuses lines deleted`) (t `@minuses lines edited to @pluses lines`)))) (put-line `@path:@(+ line1 start):@wording`) (put-lines (nreverse old)) (set minuses 0 pluses 0 start nil old nil)))) @ (end) @ (until) @/[^+\- ]/@nil @ (end) @ (until) --- @(skip) @ (end) @(end)