replaceRange method
Replace a range of text with new text. Used for clipboard operations and text manipulation.
Implementation
void replaceRange(
int start,
int end,
String replacement, {
bool preserveOldCursor = false,
}) {
if (_undoController?.isUndoRedoInProgress ?? false) return;
final selectionBefore = _selection;
_flushBuffer();
final safeStart = start.clamp(0, _rope.length);
final safeEnd = end.clamp(safeStart, _rope.length);
final deletedText = safeStart < safeEnd
? _rope.substring(safeStart, safeEnd)
: '';
if (safeStart < safeEnd) {
_rope.delete(safeStart, safeEnd);
}
if (replacement.isNotEmpty) {
_rope.insert(safeStart, replacement);
}
_currentVersion++;
TextSelection newSelection;
if (preserveOldCursor) {
final delta = replacement.length - (safeEnd - safeStart);
int mapOffset(int offset) {
if (offset <= safeStart) return offset;
if (offset >= safeEnd) return (offset + delta).clamp(0, _rope.length);
final relative = offset - safeStart;
final mapped = safeStart + relative.clamp(0, replacement.length);
return mapped.clamp(0, _rope.length);
}
final base = mapOffset(selectionBefore.baseOffset);
final extent = mapOffset(selectionBefore.extentOffset);
newSelection = TextSelection(baseOffset: base, extentOffset: extent);
} else {
newSelection = TextSelection.collapsed(
offset: safeStart + replacement.length,
);
}
_selection = newSelection;
dirtyLine = _rope.getLineAtOffset(safeStart);
dirtyRegion = TextRange(
start: safeStart,
end: safeStart + replacement.length,
);
if (deletedText.isNotEmpty && replacement.isNotEmpty) {
_recordReplacement(
safeStart,
deletedText,
replacement,
selectionBefore,
_selection,
);
} else if (deletedText.isNotEmpty) {
_recordDeletion(safeStart, deletedText, selectionBefore, _selection);
} else if (replacement.isNotEmpty) {
_recordInsertion(safeStart, replacement, selectionBefore, _selection);
}
if (connection != null && connection!.attached) {
_lastSentText = text;
_lastSentSelection = _selection;
connection!.setEditingState(
TextEditingValue(text: _lastSentText!, selection: _selection),
);
}
notifyListeners();
}