reindentDocument method
void
reindentDocument(
{ - required int newTabSize,
})
Implementation
void reindentDocument({required int newTabSize}) {
final oldTabSize = detectIndentation();
if (oldTabSize <= 0 || newTabSize <= 0 || oldTabSize == newTabSize) {
tabSize = 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 match = RegExp(r"^[ \t]+").firstMatch(line);
if (match == null) {
newLines.add(line);
continue;
}
final leadingWhitespace = match.group(0)!;
final content = line.substring(leadingWhitespace.length);
int visualSpaces = 0;
for (int i = 0; i < leadingWhitespace.length; i++) {
if (leadingWhitespace[i] == '\t') {
visualSpaces += oldTabSize - (visualSpaces % oldTabSize);
} else {
visualSpaces += 1;
}
}
final indentLevels = visualSpaces ~/ oldTabSize;
final remainder = visualSpaces % oldTabSize;
final newIndentLength = (indentLevels * newTabSize) + remainder;
newLines.add("${' ' * newIndentLength}$content");
}
final newText = newLines.join("\n");
tabSize = newTabSize;
if (newText == originalText) return;
final newLineStarts = _lineStarts(newText);
final originalLineStarts = _lineStarts(originalText);
final mappedSelection = TextSelection(
baseOffset: _mapOffsetForReindent(
originalOffset: originalSelection.baseOffset,
originalText: originalText,
newText: newText,
originalLineStarts: originalLineStarts,
newLineStarts: newLineStarts,
),
extentOffset: _mapOffsetForReindent(
originalOffset: originalSelection.extentOffset,
originalText: originalText,
newText: newText,
originalLineStarts: originalLineStarts,
newLineStarts: newLineStarts,
),
);
text = newText;
selection = mappedSelection;
}