Changing the -U context size or switching pagers preserves the scroll
position by scanning the re-rendered diff for the line to land on. Each scan
resolved every buffer line through the per-line resolver, whose buffer-parse
backend re-parses that line's whole file section on every call — so a scan was
O(n2) in the diff length. On a 9600-line diff, changing context took ~33s with
no pager (worse with delta); the file/hunk navigation scans had the same cost.
Route the whole-buffer scans (the position restore's nearbyDiffLines and
end-of-load resolution, and the file/hunk navigation) through a new
resolveDiffLines, which parses each file section once for the whole buffer and
applies the metadata/buffer/hyperlink precedence on top — O(n). The incremental
restore scan now resolves only the rows that loaded since it last looked, using
the per-row backends (metadata/hyperlink) that don't need surrounding context;
the buffer-parse case still resolves once the diff is complete. The single-line
resolver (clicks) is unchanged.
Measured on a synthetic single-file diff, the whole-buffer scan drops from
1.7s to 1ms at 1700 lines and from ~107s to 15ms at 6800 lines.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>