buildPreview function
String
buildPreview(
- String body, {
- required String spillPath,
- required SpillsConfig config,
- String? thresholdNote,
Builds the symmetric preview for body — exactly what the session
stores and the model sees (issue #678 Decision). Pinned sectioning
(blank-line separated): header lines / head / omitted marker /
tail + read hint:
[spilled: <totalChars> chars, <totalLines> lines (threshold <T> chars)]
[spill file: <spillPath>]
<head — at most headChars, codepoint-safe cut>
[... <omitted> chars omitted ...]
<tail — at most tailChars, codepoint-safe cut>
[read the spill file above for the full output]
Char-bounded (never line-counted — a single giant line stays bounded,
AC3), UTF-16 surrogate-pair-safe (AC4), and the omitted marker
([... N chars omitted ...]) carries the TRUE omitted size (AC10).
Pure function.
Implementation
String buildPreview(
String body, {
required String spillPath,
required SpillsConfig config,
String? thresholdNote,
}) {
final note = thresholdNote ?? 'threshold ${config.threshold} chars';
// A body the preview bounds already cover renders ONCE — the naive
// head+tail concat would duplicate it with a negative omitted count
// (gh-1604: a bench threshold below head+tail bounds must not double
// the body into the "bounded" preview).
if (body.length <= config.headChars + config.tailChars) {
final lines = '\n'.allMatches(body).length + 1;
return '[spilled: ${body.length} chars, $lines lines ($note)]\n'
'[spill file: $spillPath]\n'
'\n'
'$body\n'
'$spillReadHint';
}
final head = _headExcerpt(body, config.headChars);
final tail = _tailExcerpt(body, config.tailChars);
final omitted = body.length - head.length - tail.length;
final lines = '\n'.allMatches(body).length + 1;
return '[spilled: ${body.length} chars, $lines lines ($note)]\n'
'[spill file: $spillPath]\n'
'\n'
'$head\n'
'\n'
'[... $omitted chars omitted ...]\n'
'\n'
'$tail\n'
'$spillReadHint';
}