backspaceAtAllCursors method

void backspaceAtAllCursors()

Performs backspace at all cursor positions (primary + secondary).

Implementation

void backspaceAtAllCursors() {
  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 > 0) {
      final deleteStart = (offset - 1).clamp(0, _rope.length);
      final deletedChar = _rope.substring(deleteStart, offset);
      _rope.delete(deleteStart, offset);
      _currentVersion++;

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

  compound?.end();

  final primaryIndex = uniqueOffsets.indexOf(primaryOffset);
  final primaryShift = primaryOffset > 0 ? primaryIndex + 1 : 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];
    if (origOffset <= 0) continue;
    final newOffset = (origOffset - (k + 1)).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);
  _scheduleSyncToConnection();
  notifyListeners();
}