AddLine re-wrapped every stored line on each append, and the buffer it
re-wrapped had no upper bound, so the work a session did grew as the square
of its length. Wrapping also built each display line by concatenating one
rune at a time, reallocating per character.
Wrap just the line being added, build it with a strings.Builder, and cap the
retained history. Trimming is done a block at a time because it forces a
rebuild; discarding a single line per append would re-wrap the whole buffer
again.
Measured over the same benchmark, 4000 lines went from 42s and 18.8GB
allocated to 4ms and 1MB, and 20000 lines now complete in 85ms.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>