replaceText static method

TextStory replaceText({
  1. required TextStory story,
  2. required int blockIndex,
  3. required int start,
  4. required int end,
  5. required String text,
  6. ({TextRunAttributes? value})? attributes,
  7. TextRun? typingStyle,
})

Replaces a block-local text range without flattening unaffected rich-text runs. The inserted text takes the explicitly supplied run attributes (a null value clears them), or else those of typingStyle or of the run immediately before/after the caret. Range endpoints may be supplied in either direction and are clamped to the block after normalization.

Implementation

static TextStory replaceText({
  required TextStory story,
  required int blockIndex,
  required int start,
  required int end,
  required String text,
  ({TextRunAttributes? value})? attributes,
  TextRun? typingStyle,
}) {
  final block = story.blocks[blockIndex];
  final length = block.plainText.length;
  final safeStart = math.min(start, end).clamp(0, length);
  final safeEnd = math.max(start, end).clamp(0, length);
  final insertionStyle = typingStyle ?? _styleAt(block.runs, safeStart);
  final replacement = text.isEmpty
      ? const <TextRun>[]
      : [
          insertionStyle.copyWith(
            text: text,
            attributes: attributes == null
                ? insertionStyle.attributes
                : attributes.value,
          ),
        ];
  final retained = [
    ...sliceTextRuns(block.runs, 0, safeStart),
    ...replacement,
    ...sliceTextRuns(block.runs, safeEnd, length),
  ];
  return story.replaceBlock(
    block.copyWith(
      runs: retained.isEmpty
          ? [_styleAt(block.runs, safeStart).copyWith(text: '')]
          : _mergeRuns(retained),
    ),
  );
}