Adds TruncateString(s string, max int) string, which returns at most max
characters from the start of the string. A max of zero or less returns an empty
string, and a string already within the limit comes back unchanged.
This belongs here because every program that puts text into a fixed-width
column, a log line or a summary needs to shorten it, and the obvious way of
doing that, s[:max], is wrong for any text that is not plain ASCII: it splits
a multi-byte character and produces invalid output. The correct version is
short but not obvious.
Things to know:
The limit counts characters, not bytes and not display width. Text with
combining marks, or with characters that a terminal draws double width, will
still count as one character each, so this is not a way to fit text into a
fixed number of screen columns.
The implementation walks the string with range, which yields the byte
offset of each character start, so nothing is allocated and no conversion to
a rune slice happens.
Nothing is appended to the result, so there is no ellipsis. A caller that
wants one can add it, and can decide whether it counts against the limit.
The code is in a new file, truncate.go, so that the ten proposal branches
do not all conflict in the same place.
make test on this branch reports one failure, TestNowUnixMicro. That test
already fails on master and is unrelated to this change.
Model: opus-5
Adds `TruncateString(s string, max int) string`, which returns at most `max`
characters from the start of the string. A max of zero or less returns an empty
string, and a string already within the limit comes back unchanged.
This belongs here because every program that puts text into a fixed-width
column, a log line or a summary needs to shorten it, and the obvious way of
doing that, `s[:max]`, is wrong for any text that is not plain ASCII: it splits
a multi-byte character and produces invalid output. The correct version is
short but not obvious.
Things to know:
- The limit counts characters, not bytes and not display width. Text with
combining marks, or with characters that a terminal draws double width, will
still count as one character each, so this is not a way to fit text into a
fixed number of screen columns.
- The implementation walks the string with `range`, which yields the byte
offset of each character start, so nothing is allocated and no conversion to
a rune slice happens.
- Nothing is appended to the result, so there is no ellipsis. A caller that
wants one can add it, and can decide whether it counts against the limit.
- The code is in a new file, `truncate.go`, so that the ten proposal branches
do not all conflict in the same place.
- `make test` on this branch reports one failure, `TestNowUnixMicro`. That test
already fails on `master` and is unrelated to this change.
Model: opus-5
clawbot
self-assigned this 2026-09-05 05:25:10 +02:00
TruncateString returns at most the requested number of characters from the
start of a string, counting characters rather than bytes so a multi-byte
character is never cut in half. Comes with a doc comment and table-driven
tests. (closes#5)
Model: opus-5
sneak
merged commit 1a6d1b429b into master2026-09-05 05:45:39 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Adds
TruncateString(s string, max int) string, which returns at mostmaxcharacters from the start of the string. A max of zero or less returns an empty
string, and a string already within the limit comes back unchanged.
This belongs here because every program that puts text into a fixed-width
column, a log line or a summary needs to shorten it, and the obvious way of
doing that,
s[:max], is wrong for any text that is not plain ASCII: it splitsa multi-byte character and produces invalid output. The correct version is
short but not obvious.
Things to know:
combining marks, or with characters that a terminal draws double width, will
still count as one character each, so this is not a way to fit text into a
fixed number of screen columns.
range, which yields the byteoffset of each character start, so nothing is allocated and no conversion to
a rune slice happens.
wants one can add it, and can decide whether it counts against the limit.
truncate.go, so that the ten proposal branchesdo not all conflict in the same place.
make teston this branch reports one failure,TestNowUnixMicro. That testalready fails on
masterand is unrelated to this change.Model: opus-5