reindentDocument method

void reindentDocument({
  1. required int oldTabSize,
  2. required int newTabSize,
})

Implementation

void reindentDocument({required int oldTabSize, required int newTabSize}) {
  if (oldTabSize <= 0 || newTabSize <= 0 || oldTabSize == newTabSize) {
    return;
  }

  final originalText = text;
  if (originalText.isEmpty) {
    tabSize = newTabSize;
    return;
  }

  final originalSelection = selection;
  final originalLines = originalText.split("\n");
  final newLines = <String>[];

  for (final line in originalLines) {
    final leadingWhitespace =
        RegExp(r"^[ \t]+", multiLine: true).stringMatch(line) ?? "";
    final content = line.substring(leadingWhitespace.length);
    final indentLength = leadingWhitespace
        .replaceAll("\t", " " * oldTabSize)
        .length;
    final indentLevels = indentLength ~/ oldTabSize;
    final newIndentLength = indentLevels * newTabSize;
    newLines.add("${" " * newIndentLength}$content");
  }

  final newText = newLines.join("\n");
  if (newText == originalText) {
    tabSize = newTabSize;
    return;
  }

  final newLineStarts = _lineStarts(newText);
  final originalLineStarts = _lineStarts(originalText);

  final newSelection = TextSelection(
    baseOffset: _mapOffsetForReindent(
      originalOffset: originalSelection.start,
      originalText: originalText,
      newText: newText,
      oldTabSize: oldTabSize,
      newTabSize: newTabSize,
      originalLineStarts: originalLineStarts,
      newLineStarts: newLineStarts,
    ),
    extentOffset: _mapOffsetForReindent(
      originalOffset: originalSelection.end,
      originalText: originalText,
      newText: newText,
      oldTabSize: oldTabSize,
      newTabSize: newTabSize,
      originalLineStarts: originalLineStarts,
      newLineStarts: newLineStarts,
    ),
  );

  text = newText;
  selection = newSelection;
  tabSize = newTabSize;
}