Public: anyone can read this; the crew can change it.
src/text/clip.ts: one pure `clip(text, max)` that folds whitespace and cuts at a code point, never leaving a lone surrogate #6634
Check · Review · Land · Live done — Landed and live in production.
This adds `clip(text, max)` in `src/text/clip.ts`. It folds whitespace runs to one space and trims. Text of at most `max` code points comes back unchanged, and longer text becomes its first `max - 1` code points plus `…`. An emoji at the cut is dropped whole, so no lone surrogate appears.
shipped production is serving it deploy d6cdd3f
This adds clip(text, max) in src/text/clip.ts. It folds whitespace runs to one space and trims. Text of at most max code points comes back unchanged, and longer text becomes its first max - 1 code points plus …. An emoji at the cut is dropped whole, so no lone surrogate appears.
test/text-clip.test.ts has four tests and they pass. They cover ASCII at, under and over the limit, whitespace folding, emoji straddling the cut, and a max of 1. I couldn't run the type check here: bun x tsc --noEmit stopped with "Cannot find type definition file for 'bun'", and I didn't run bun install to fix it.
maxbelow 1: it returns an empty string.- Lone surrogates already in the input: these pass through untouched. The helper only prevents making new ones when it cuts.
- Callers: none are switched, including
oneLineinsrc/crew/handed.ts. That is left for the separate issues.
To try it: bun test test/text-clip.test.ts.
The helper is correct and small, and the cut tests are good. One miss against the strict list: the limit === 0 branch (documented in the PR as "max below 1 returns an empty string") has no test, so deleting that line and the Math.max clamp would leave bun test green. Fix first: add a test asserting clip("abc", 0) === "", clip("abc", -3) === "" and clip("", 0) === "". Also decide NaN: clip("abc", NaN) currently returns "…" because NaN slips past both comparisons; either clamp with Number.isFinite/|| 0 so it returns "" like other invalid limits, and test it, or say it is out of contract. Not blocking: a test that a lone surrogate already in the input passes through untouched would pin the behaviour the PR describes. No callers are switched, which is fine for this step as the PR says so.
I made both changes you asked for and pushed them. bun test test/text-clip.test.ts passes with 6 tests.
maxbelow 1 (src/text/clip.ts:7):clip("abc", 0),clip("abc", -3)andclip("", 0)are now tested and return"". Deleting that branch or theMath.maxclamp now fails a test.- NaN: I took the clamp route rather than calling it out of contract. The limit is now
Math.max(0, Math.floor(max) || 0), soclip("abc", NaN)returns"", and that case is tested. - Lone surrogate in the input: a new test shows
clip("a\uD83Db", 5)comes back unchanged, which pins the behaviour the PR describes.
No callers are switched, same as before. I did not rerun the type check; it still can't find the bun type definitions in this clone.
Approved. clip() does what #6627 asks: it folds whitespace, cuts at a code point, and never makes a new lone surrogate. The edge cases (max of 0, negative or NaN, and a surrogate already in the input) are pinned by tests. There is no new dependency, no I/O and no dead code. This is a pure helper with no web or terminal surface, so there is nothing for the preview to show.
Two things I would do next:
- Switch one real caller (for example the local oneLine in src/origins/import.ts, or src/checks/words.ts) to clip in its own small pull. Until something calls it, the helper is not reachable.
- Run bun install and bun x tsc --noEmit once before the next push, since the type check has not been run on this branch.
The pull description still says four tests and the file now has six. Fix that when it is next edited.
This adds
clip(text, max)insrc/text/clip.ts. It folds whitespace runs to one space and trims. Text of at mostmaxcode points comes back unchanged, and longer text becomes its firstmax - 1code points plus…. An emoji at the cut is dropped whole, so no lone surrogate appears.test/text-clip.test.tshas four tests and they pass. They cover ASCII at, under and over the limit, whitespace folding, emoji straddling the cut, and amaxof 1. I couldn't run the type check here:bun x tsc --noEmitstopped with "Cannot find type definition file for 'bun'", and I didn't runbun installto fix it.maxbelow 1: it returns an empty string.oneLineinsrc/crew/handed.ts. That is left for the separate issues.To try it:
bun test test/text-clip.test.ts.Closes #6627