void (final @NotNull List<? extends LeafBlockWrapper> blocksToModify, final @NotNull FormattingModel model) { FormattingDocumentModel documentModel = model.getDocumentModel(); Document document = documentModel.getDocument(); CaretOffsetUpdater caretOffsetUpdater = new CaretOffsetUpdater(document); DocumentUtil.executeInBulk(document, ()->{ List<TextChange> changes = new ArrayList<>(); int shift = 0; int currentIterationShift = 0; for (LeafBlockWrapper block : blocksToModify) { WhiteSpace whiteSpace = block.getWhiteSpace(); CharSequence newWs = documentModel.adjustWhiteSpaceIfNecessary( whiteSpace.generateWhiteSpace(myBlockIndentOptions.getIndentOptions(block)), whiteSpace.getStartOffset(), whiteSpace.getEndOffset(), block.getNode(), false ); if (changes.size() > 10000) { caretOffsetUpdater.update(changes); CharSequence mergeResult = BulkChangesMerger.INSTANCE.mergeToCharSequence(document.getChars(), document.getTextLength(), changes); document.replaceString(0, document.getTextLength(), mergeResult); shift += currentIterationShift; currentIterationShift = 0; changes.clear(); } TextChangeImpl change = new TextChangeImpl(newWs, whiteSpace.getStartOffset() + shift, whiteSpace.getEndOffset() + shift); currentIterationShift += change.getDiff(); changes.add(change); } caretOffsetUpdater.update(changes); CharSequence mergeResult = BulkChangesMerger.INSTANCE.mergeToCharSequence(document.getChars(), document.getTextLength(), changes); document.replaceString(0, document.getTextLength(), mergeResult); }); caretOffsetUpdater.restoreCaretLocations(); cleanupBlocks(blocksToModify); }