toggleDelimitedSegment function
TextCommandResult
toggleDelimitedSegment(
- List<String> graphemes, {
- required int cursorOffset,
- int? selectionBaseOffset,
- int? selectionExtentOffset,
- required int rangeStartOffset,
- required int rangeEndOffset,
- required String startDelimiter,
- required String endDelimiter,
})
Implementation
TextCommandResult toggleDelimitedSegment(
List<String> graphemes, {
required int cursorOffset,
int? selectionBaseOffset,
int? selectionExtentOffset,
required int rangeStartOffset,
required int rangeEndOffset,
required String startDelimiter,
required String endDelimiter,
}) {
final selection = normalizedSelectionRange(
selectionBaseOffset,
selectionExtentOffset,
);
final hasSelection = selection != null && selection.start != selection.end;
final start = hasSelection ? selection.start : rangeStartOffset;
final end = hasSelection ? selection.end : rangeEndOffset;
if (start >= end) {
return _unchangedResult(
graphemes,
cursorOffset: cursorOffset,
selectionBaseOffset: selectionBaseOffset,
selectionExtentOffset: selectionExtentOffset,
);
}
final clampedStart = start.clamp(0, graphemes.length);
final clampedEnd = end.clamp(0, graphemes.length);
if (clampedStart >= clampedEnd) {
return _unchangedResult(
graphemes,
cursorOffset: cursorOffset,
selectionBaseOffset: selectionBaseOffset,
selectionExtentOffset: selectionExtentOffset,
);
}
final startGraphemes = startDelimiter.characters.toList(growable: false);
final endGraphemes = endDelimiter.characters.toList(growable: false);
final segment = graphemes.sublist(clampedStart, clampedEnd);
final leadingWhitespace = _leadingWhitespaceCount(segment);
final trailingWhitespace = _trailingWhitespaceCount(segment);
final coreEnd = segment.length - trailingWhitespace;
final core = segment.sublist(leadingWhitespace, coreEnd);
List<String> replacement;
var selectionStart = leadingWhitespace;
late int selectionEnd;
if (_startsWithGraphemeSequence(core, startGraphemes) &&
_endsWithGraphemeSequence(core, endGraphemes)) {
var innerStart = leadingWhitespace + startGraphemes.length;
var innerEnd = coreEnd - endGraphemes.length;
if (innerStart < innerEnd && segment[innerStart] == ' ') {
innerStart++;
}
if (innerStart < innerEnd && segment[innerEnd - 1] == ' ') {
innerEnd--;
}
replacement = <String>[
...segment.sublist(0, leadingWhitespace),
...segment.sublist(innerStart, innerEnd),
...segment.sublist(coreEnd),
];
selectionEnd = selectionStart + (innerEnd - innerStart);
} else {
final separator = core.isEmpty ? const <String>[] : const <String>[' '];
replacement = <String>[
...segment.sublist(0, leadingWhitespace),
...startGraphemes,
...separator,
...core,
...separator,
...endGraphemes,
...segment.sublist(coreEnd),
];
selectionEnd =
selectionStart +
startGraphemes.length +
separator.length +
core.length +
separator.length +
endGraphemes.length;
}
if (_listStringEquals(replacement, segment)) {
return _unchangedResult(
graphemes,
cursorOffset: cursorOffset,
selectionBaseOffset: selectionBaseOffset,
selectionExtentOffset: selectionExtentOffset,
);
}
final result = edit_ops.replaceRange(
graphemes,
start: clampedStart,
end: clampedEnd,
replacement: replacement,
);
final nextSelectionStart = clampedStart + selectionStart;
final nextSelectionEnd = clampedStart + selectionEnd;
if (hasSelection) {
return TextCommandResult(
graphemes: result.graphemes,
cursorOffset: nextSelectionEnd,
selectionBaseOffset: nextSelectionStart,
selectionExtentOffset: nextSelectionEnd,
);
}
return TextCommandResult(
graphemes: result.graphemes,
cursorOffset: nextSelectionEnd,
);
}