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 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));
}
multiCursorsChanged = true;
dirtyRegion = TextRange(start: 0, end: _rope.length);
_invalidateImeSnapshotAndScheduleSync();
notifyListeners();
}