removeCells method

void removeCells(
  1. int start,
  2. int count, [
  3. CursorStyle? style,
  4. int? end,
])

Remove count cells starting at start. Cells that are empty after the removal are filled with style.

Implementation

void removeCells(int start, int count, [CursorStyle? style, int? end]) {
  end ??= _length;
  assert(start >= 0 && start < _length);
  assert(end >= start && end <= _length);
  assert(count >= 0 && start + count <= end);

  if (count == 0) return;

  style ??= CursorStyle.empty;
  final combiningCharacters = switch (_combiningCharacters) {
    final values? when values.isNotEmpty => Map<int, String>.of(values),
    _ => const <int, String>{},
  };
  final underlineColors = switch (_underlineColors) {
    final values? when values.isNotEmpty => Map<int, int>.of(values),
    _ => const <int, int>{},
  };
  final rightBoundarySplitsWideCell =
      end < _length && end > 0 && getWidth(end - 1) == 2;

  if (start + count < end) {
    final moveStart = start * _cellSize;
    final moveEnd = (end - count) * _cellSize;
    final moveOffset = count * _cellSize;
    _data.setRange(moveStart, moveEnd, _data, moveStart + moveOffset);
  }

  for (var i = end - count; i < end; i++) {
    eraseCell(i, style);
  }

  if (start > 0 && getWidth(start - 1) == 2) {
    eraseCell(start - 1, style);
  }
  if (rightBoundarySplitsWideCell) {
    final shiftedHead = end - count - 1;
    if (shiftedHead >= start && shiftedHead < _length) {
      eraseCell(shiftedHead, style);
    }
    eraseCell(end, style);
  }

  _combiningCharacters = null;
  _underlineColors = null;
  for (final entry in combiningCharacters.entries) {
    if (entry.key < start) {
      if (getCodePoint(entry.key) != 0) {
        _mutableCombiningCharacters[entry.key] = entry.value;
      }
      continue;
    }

    if (entry.key < start + count) continue;
    final newIndex = entry.key - count;
    if (entry.key < end &&
        newIndex < _length &&
        getCodePoint(newIndex) != 0) {
      _mutableCombiningCharacters[newIndex] = entry.value;
      continue;
    }

    if (entry.key >= end && getCodePoint(entry.key) != 0) {
      _mutableCombiningCharacters[entry.key] = entry.value;
    }
  }
  for (final entry in underlineColors.entries) {
    if (entry.key < start) {
      if (getCodePoint(entry.key) != 0) {
        _mutableUnderlineColors[entry.key] = entry.value;
      }
      continue;
    }

    if (entry.key < start + count) continue;
    final newIndex = entry.key - count;
    if (entry.key < end &&
        newIndex < _length &&
        getCodePoint(newIndex) != 0) {
      _mutableUnderlineColors[newIndex] = entry.value;
      continue;
    }

    if (entry.key >= end && getCodePoint(entry.key) != 0) {
      _mutableUnderlineColors[entry.key] = entry.value;
    }
  }

  // Update anchors, remove anchors that are inside the removed range.
  if (_anchors.isNotEmpty) {
    for (final anchor in _anchors.toList()) {
      if (anchor.x >= start) {
        if (anchor.x < start + count) {
          anchor.dispose();
        } else if (anchor.x < end) {
          anchor.reposition(anchor.x - count);
        }
      }
    }
  }
}