deleteAtAllCursors method

void deleteAtAllCursors()

Performs deletion operation at all cursor positions.

Implementation

void deleteAtAllCursors() {
  if (readOnly || _multiCursors.isEmpty) return;

  _flushBuffer();

  final selectionBefore = _selection;
  final multiCursorsBeforeSnapshot = List<({int line, int character})>.from(
    _multiCursors,
  );
  final primaryOffset = selection.extentOffset.clamp(0, _rope.length);
  final offsets = <int>[primaryOffset];
  for (final c in _multiCursors) {
    offsets.add(_multiCursorToOffset(c).clamp(0, _rope.length));
  }

  final uniqueOffsets = offsets.toSet().toList()
    ..sort((a, b) => a.compareTo(b));

  final compound = _undoController?.beginCompoundOperation();

  for (final offset in uniqueOffsets.reversed) {
    if (offset < _rope.length) {
      final deletedChar = _rope.substring(offset, offset + 1);
      _rope.delete(offset, offset + 1);
      _currentVersion++;

      _recordDeletion(
        offset,
        deletedChar,
        selectionBefore,
        TextSelection.collapsed(offset: offset),
      );
    }
  }

  compound?.end();

  final primaryIndex = uniqueOffsets.indexOf(primaryOffset);
  final primaryShift = primaryOffset < _rope.length + primaryIndex
      ? primaryIndex
      : 0;
  final primaryNewOffset = (primaryOffset - primaryShift).clamp(
    0,
    _rope.length,
  );
  _selection = TextSelection.collapsed(offset: primaryNewOffset);

  _multiCursors.clear();
  for (int k = 0; k < uniqueOffsets.length; k++) {
    final origOffset = uniqueOffsets[k];
    final newOffset = (origOffset - k).clamp(0, _rope.length);
    if (newOffset == primaryNewOffset) continue;
    final newLine = _rope.getLineAtOffset(newOffset);
    final newLineStart = _rope.getLineStartOffset(newLine);
    _multiCursors.add((line: newLine, character: newOffset - newLineStart));
  }

  _patchLastCompoundMultiCursors(
    before: multiCursorsBeforeSnapshot,
    after: List<({int line, int character})>.from(_multiCursors),
  );

  dirtyRegion = TextRange(start: 0, end: _rope.length);
  _imeProjectionDirty = true;
  _imeSelectionNeedsResync = true;
  _scheduleSyncToConnection();
  notifyListeners();
}