Problem
When using CodeEditor.maxLengthSingleLineRendering, Re-Editor truncates a long single line by doing substring(0, N) on TextSpan.text / plainText. This counts UTF-16 code units and may cut in the middle of a grapheme cluster (surrogate pairs, ZWJ sequences, variation selectors).
This can lead to broken rendering (e.g. replacement character "�"), and potentially inconsistent caret/selection hit-testing near the truncation boundary.
Where
lib/src/_code_paragraph.dart:
// current implementation
if (renderingLength != null && plainText.length > renderingLength) {
impl = _build(trucate(span, renderingLength), plainText.substring(0, renderingLength), true);
}
TextSpan trucate(TextSpan span, int maxLength) {
// ...
if (text.length > remainingLength) {
text = text.substring(0, remainingLength);
}
// ...
}
Repro
- Enable
wordWrap: true
- Set
maxLengthSingleLineRendering to a small number
- Type/paste an emoji sequence around the boundary, e.g.:
- Surrogate pair:
😀
- ZWJ sequence:
👨👩👧👦 or 👩❤️💋👩
- If truncation cuts inside the sequence, rendering becomes broken.
Suggestion
Make truncation grapheme-safe:
- Use
package:characters (grapheme cluster iterator) to compute a safe prefix length <= maxLength (code units) and truncate at cluster boundaries.
- Apply the same safe length to both the span truncation and the
plainText substring.
This keeps the performance guard while avoiding invalid Unicode sequences.
Thanks!
Problem
When using
CodeEditor.maxLengthSingleLineRendering, Re-Editor truncates a long single line by doingsubstring(0, N)onTextSpan.text/plainText. This counts UTF-16 code units and may cut in the middle of a grapheme cluster (surrogate pairs, ZWJ sequences, variation selectors).This can lead to broken rendering (e.g. replacement character "�"), and potentially inconsistent caret/selection hit-testing near the truncation boundary.
Where
lib/src/_code_paragraph.dart:Repro
wordWrap: truemaxLengthSingleLineRenderingto a small number😀👨👩👧👦or👩❤️💋👩Suggestion
Make truncation grapheme-safe:
package:characters(grapheme cluster iterator) to compute a safe prefix length <= maxLength (code units) and truncate at cluster boundaries.plainTextsubstring.This keeps the performance guard while avoiding invalid Unicode sequences.
Thanks!