replaceTextRange method

TextDocumentChange replaceTextRange({
  1. required int startOffset,
  2. required int endOffset,
  3. String replacement = '',
})

Implementation

TextDocumentChange replaceTextRange({
  required int startOffset,
  required int endOffset,
  String replacement = '',
}) {
  final normalizedStart = startOffset.clamp(0, length);
  final normalizedEnd = endOffset.clamp(normalizedStart, length);
  final startPosition = positionForOffset(normalizedStart);
  final oldEndPosition = positionForOffset(normalizedEnd);
  final replacementLength = replacement.characters.length;
  if (normalizedStart + replacementLength == normalizedEnd &&
      textInRange(startOffset: normalizedStart, endOffset: normalizedEnd) ==
          replacement) {
    return TextDocumentChange(
      startOffset: normalizedStart,
      oldEndOffset: normalizedEnd,
      newEndOffset: normalizedEnd,
      startPosition: startPosition,
      oldEndPosition: oldEndPosition,
      newEndPosition: oldEndPosition,
    );
  }

  final replacementLineTexts = _parseLineTexts(replacement);
  final replacementLineLengths = _computeLineTextStats(
    replacementLineTexts,
  ).lineLengths;
  final replacementStorage =
      _pieceBackedReplacementStorageFromLineTexts(
        storage: _storage,
        startPosition: startPosition,
        oldEndPosition: oldEndPosition,
        replacementLineTexts: replacementLineTexts,
        replacementLineLengths: replacementLineLengths,
      ) ??
      (() {
        final prefixText = _storage.lineTextPrefix(
          startPosition.line,
          startPosition.column,
        );
        final suffixText = _storage.lineTextSuffix(
          oldEndPosition.line,
          oldEndPosition.column,
        );
        final mergedReplacementText = prefixText.isEmpty && suffixText.isEmpty
            ? replacement
            : '$prefixText$replacement$suffixText';
        return _replacementStorageFromText(
          mergedReplacementText,
          revision: 0,
        );
      })();
  final nextSegments = <_TextDocumentStorageSegment>[
    if (startPosition.line > 0) _storage.slice(0, startPosition.line),
    replacementStorage.slice(0, replacementStorage.lineCount),
    if (oldEndPosition.line + 1 < _storage.lineCount)
      _storage.slice(oldEndPosition.line + 1, _storage.lineCount),
  ];
  _storage = _storageBuilder.fromSegments(
    nextSegments,
    revision: _storage.revision + 1,
  );

  final newEndOffset = normalizedStart + replacementLength;
  return TextDocumentChange(
    startOffset: normalizedStart,
    oldEndOffset: normalizedEnd,
    newEndOffset: newEndOffset,
    startPosition: startPosition,
    oldEndPosition: oldEndPosition,
    newEndPosition: positionForOffset(newEndOffset),
  );
}