Never split an emoji at the edge of a find snippet or a cut read - #120
Merged
only-cli merged 1 commit intoSep 28, 2026
Merged
Conversation
only-cli#115 stopped the compact view's cap from printing half of a character past U+FFFF. Two other cuts count UTF-16 units the same way and were left as they were: find's snippet window, which opens 60 units before the match and runs 200, and read's cut of a first block bigger than its whole budget, at budget * 4 units. Either edge can land between the two halves of an emoji, and then the line carries a lone surrogate, which a terminal prints as the replacement character. Each edge now steps back one unit when it would land there, the rule render.js already uses. A snippet's opening edge so takes the whole emoji, and its closing edge and read's cut leave it out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#115 stopped the compact view's cap from printing half of a character past U+FFFF. Two other cuts in
src/act.jscount UTF-16 units the same way and still split one:find's snippet window (search) opens 60 units before the match and runs 200.read's cut of a first block bigger than its whole budget stops atbudget * 4units.Either edge can land between the two halves of an emoji, and the line then carries a lone surrogate, which a terminal prints as
�. A block with the match 60 units after an emoji, and another emoji 200 units on, printed asoc find needleon a page with enough matches to use snippets:Change. Each edge steps back one unit when it would land between the halves, the rule
render.jsalready uses at the cap. The snippet's opening edge so takes the whole emoji, and its closing edge andread's cut leave it out. The window width, the...markers, and thereadbudget are otherwise unchanged.Test.
tests/act.test.jsgains one test covering both: a snippet whose window opens and closes inside an emoji, and aread --budget 10whose cut at character 40 lands inside one. Onmainthe snippet half fails; with only the snippet fixed, thereadhalf still fails (xxx\ud83d ... cut at ~10 tokens), so each half guards its own edge. Full suite on Windows (Node 24): 316 tests, 313 pass, 3 skipped, 0 fail.Left alone. The JSON view's
same on every itemline also cuts a value at 60 units (v.slice(0, 60)injsonToHTML). It is a different view, so I kept it out of this change. No CHANGELOG line, to keep this round's PRs from conflicting there.🤖 Generated with Claude Code