backspace method
void
backspace()
Remove the selection or last char if the selection is empty (backspace key)
Implementation
void backspace() {
if (readOnly) return;
if (_undoController?.isUndoRedoInProgress ?? false) return;
final selectionBefore = _selection;
final sel = _selection;
String deletedText;
if (sel.start < sel.end) {
_flushBuffer();
// Check if we're deleting the entire first line of a folded range
if (deleteFoldRangeOnDeletingFirstLine) {
final startLine = _rope.getLineAtOffset(sel.start);
final endLine = _rope.getLineAtOffset(sel.end);
// Check if selection is on a single line (or spans to next line's start)
if (startLine == endLine ||
(startLine + 1 == endLine &&
sel.end == _rope.getLineStartOffset(endLine))) {
final lineStart = _rope.getLineStartOffset(startLine);
final lineText = _rope.getLineText(startLine);
final lineEnd = lineStart + lineText.length;
// Check if the entire line is selected (whole line or line without newline)
final selectsWholeLine = sel.start <= lineStart && sel.end >= lineEnd;
if (selectsWholeLine && _isFirstLineOfFoldedRange(startLine)) {
// Delete the entire folded range
final foldRange = foldings[startLine]!;
final foldStart = _rope.getLineStartOffset(foldRange.startIndex);
final foldEndLine = foldRange.endIndex;
final foldEndLineText = _rope.getLineText(foldEndLine);
final foldEnd =
_rope.getLineStartOffset(foldEndLine) + foldEndLineText.length;
deletedText = _rope.substring(foldStart, foldEnd);
_rope.delete(foldStart, foldEnd);
_currentVersion++;
_selection = TextSelection.collapsed(offset: foldStart);
dirtyLine = _rope.getLineAtOffset(foldStart.clamp(0, _rope.length));
lineStructureChanged = true;
// Remove the fold from the foldings map
foldings.remove(startLine);
_recordDeletion(
foldStart,
deletedText,
selectionBefore,
_selection,
);
_syncToConnection();
notifyListeners();
return;
}
}
}
deletedText = _rope.substring(sel.start, sel.end);
_rope.delete(sel.start, sel.end);
_currentVersion++;
_selection = TextSelection.collapsed(offset: sel.start);
dirtyLine = _rope.getLineAtOffset(sel.start);
_recordDeletion(sel.start, deletedText, selectionBefore, _selection);
_syncToConnection();
notifyListeners();
return;
}
if (sel.start <= 0) return;
final deleteOffset = sel.start - 1;
String charToDelete;
if (_bufferLineIndex != null && _bufferDirty) {
final bufferEnd = _bufferLineRopeStart + _bufferLineText!.length;
if (deleteOffset >= _bufferLineRopeStart && deleteOffset < bufferEnd) {
charToDelete = _bufferLineText![deleteOffset - _bufferLineRopeStart];
} else {
charToDelete = _rope.charAt(deleteOffset);
}
} else {
charToDelete = _rope.charAt(deleteOffset);
}
if (charToDelete == '\n') {
_flushBuffer();
_rope.delete(deleteOffset, sel.start);
_currentVersion++;
_selection = TextSelection.collapsed(offset: deleteOffset);
dirtyLine = _rope.getLineAtOffset(deleteOffset);
lineStructureChanged = true;
_recordDeletion(deleteOffset, '\n', selectionBefore, _selection);
_syncToConnection();
notifyListeners();
return;
}
if (_bufferLineIndex != null && _bufferDirty) {
final bufferEnd = _bufferLineRopeStart + _bufferLineText!.length;
if (deleteOffset >= _bufferLineRopeStart && deleteOffset < bufferEnd) {
final localOffset = deleteOffset - _bufferLineRopeStart;
deletedText = _bufferLineText![localOffset];
_bufferLineText =
_bufferLineText!.substring(0, localOffset) +
_bufferLineText!.substring(localOffset + 1);
_selection = TextSelection.collapsed(offset: deleteOffset);
_currentVersion++;
bufferNeedsRepaint = true;
_recordDeletion(deleteOffset, deletedText, selectionBefore, _selection);
_scheduleSyncToConnection();
_scheduleFlush();
notifyListeners();
return;
}
_flushBuffer();
}
final lineIndex = _rope.getLineAtOffset(deleteOffset);
_initBuffer(lineIndex);
final localOffset = deleteOffset - _bufferLineRopeStart;
if (localOffset >= 0 && localOffset < _bufferLineText!.length) {
deletedText = _bufferLineText![localOffset];
_bufferLineText =
_bufferLineText!.substring(0, localOffset) +
_bufferLineText!.substring(localOffset + 1);
_bufferDirty = true;
_selection = TextSelection.collapsed(offset: deleteOffset);
_currentVersion++;
dirtyLine = lineIndex;
bufferNeedsRepaint = true;
_recordDeletion(deleteOffset, deletedText, selectionBefore, _selection);
_scheduleSyncToConnection();
_scheduleFlush();
notifyListeners();
}
}