@Override @NotNull protected FutureTask<Boolean> prepareTask( @NotNull final PsiFile file, final boolean processChangedTextOnly) throws IncorrectOperationException { return new FutureTask<>( () -> { FormattingProgressTask.FORMATTING_CANCELLED_FLAG.set(false); try { CharSequence before = null; Document document = PsiDocumentManager.getInstance(myProject).getDocument(file); if (getInfoCollector() != null) { LOG.assertTrue(document != null); before = document.getImmutableCharSequence(); } CaretVisualPositionKeeper caretPositionKeeper = new CaretVisualPositionKeeper(document); if (processChangedTextOnly) { ChangedRangesInfo info = FormatChangedTextUtil.getInstance().getChangedRangesInfo(file); if (info != null) { CodeStyleManager.getInstance(myProject).reformatTextWithContext(file, info); } } else { Collection<TextRange> ranges = getRangesToFormat(file); CodeStyleManager.getInstance(myProject).reformatText(file, ranges); } caretPositionKeeper.restoreOriginalLocation(); if (before != null) { prepareUserNotificationMessage(document, before); } return !FormattingProgressTask.FORMATTING_CANCELLED_FLAG.get(); } catch (FilesTooBigForDiffException e) { handleFileTooBigException(LOG, e, file); return false; } catch (IncorrectOperationException e) { LOG.error(e); return false; } finally { myRanges.clear(); } }); }
public void processText( PsiFile file, final FormatTextRanges ranges, boolean doPostponedFormatting) { final Project project = file.getProject(); Document document = PsiDocumentManager.getInstance(project).getDocument(file); final List<FormatTextRanges.FormatTextRange> textRanges = ranges.getRanges(); if (document instanceof DocumentWindow) { file = InjectedLanguageManager.getInstance(file.getProject()).getTopLevelFile(file); final DocumentWindow documentWindow = (DocumentWindow) document; for (FormatTextRanges.FormatTextRange range : textRanges) { range.setTextRange(documentWindow.injectedToHost(range.getTextRange())); } document = documentWindow.getDelegate(); } final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file); if (builder != null) { if (file.getTextLength() > 0) { try { final PsiElement startElement = file.findElementAt(textRanges.get(0).getTextRange().getStartOffset()); final PsiElement endElement = file.findElementAt( textRanges.get(textRanges.size() - 1).getTextRange().getEndOffset() - 1); final PsiElement commonParent = startElement != null && endElement != null ? PsiTreeUtil.findCommonParent(startElement, endElement) : null; ASTNode node = null; if (commonParent != null) { node = commonParent.getNode(); } if (node == null) { node = file.getNode(); } for (FormatTextRanges.FormatTextRange range : ranges.getRanges()) { TextRange rangeToUse = preprocess(node, range.getTextRange()); range.setTextRange(rangeToUse); } if (doPostponedFormatting) { RangeMarker[] markers = new RangeMarker[textRanges.size()]; int i = 0; for (FormatTextRanges.FormatTextRange range : textRanges) { TextRange textRange = range.getTextRange(); int start = textRange.getStartOffset(); int end = textRange.getEndOffset(); if (start >= 0 && end > start && end <= document.getTextLength()) { markers[i] = document.createRangeMarker(textRange); markers[i].setGreedyToLeft(true); markers[i].setGreedyToRight(true); i++; } } final PostprocessReformattingAspect component = file.getProject().getComponent(PostprocessReformattingAspect.class); FormattingProgressTask.FORMATTING_CANCELLED_FLAG.set(false); component.doPostponedFormatting(file.getViewProvider()); i = 0; for (FormatTextRanges.FormatTextRange range : textRanges) { RangeMarker marker = markers[i]; if (marker != null) { range.setTextRange(TextRange.create(marker)); marker.dispose(); } i++; } } if (FormattingProgressTask.FORMATTING_CANCELLED_FLAG.get()) { return; } final FormattingModel originalModel = CoreFormatterUtil.buildModel(builder, file, mySettings, FormattingMode.REFORMAT); final FormattingModel model = new DocumentBasedFormattingModel( originalModel.getRootBlock(), document, project, mySettings, file.getFileType(), file); FormatterEx formatter = FormatterEx.getInstanceEx(); if (CodeStyleManager.getInstance(project).isSequentialProcessingAllowed()) { formatter.setProgressTask(new FormattingProgressTask(project, file, document)); } CommonCodeStyleSettings.IndentOptions indentOptions = null; if (builder instanceof FormattingModelBuilderEx) { indentOptions = ((FormattingModelBuilderEx) builder) .getIndentOptionsToUse(file, ranges, mySettings); } if (indentOptions == null) { indentOptions = mySettings.getIndentOptions(file.getFileType()); } formatter.format(model, mySettings, indentOptions, ranges); for (FormatTextRanges.FormatTextRange range : textRanges) { TextRange textRange = range.getTextRange(); wrapLongLinesIfNecessary( file, document, textRange.getStartOffset(), textRange.getEndOffset()); } } catch (IncorrectOperationException e) { LOG.error(e); } } } }