Search in sources :

Example 1 with FormatTextRanges

use of com.intellij.formatting.FormatTextRanges in project intellij-community by JetBrains.

the class FileSetFormatter method reformatFile.

private void reformatFile(@NotNull Project project, @NotNull final PsiFile file, @NotNull Document document) {
    WriteCommandAction.runWriteCommandAction(project, () -> {
        CodeFormatterFacade formatterFacade = new CodeFormatterFacade(mySettings, file.getLanguage());
        formatterFacade.processText(file, new FormatTextRanges(new TextRange(0, file.getTextLength()), true), false);
        PsiDocumentManager.getInstance(project).commitDocument(document);
    });
}
Also used : TextRange(com.intellij.openapi.util.TextRange) CodeFormatterFacade(com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade) FormatTextRanges(com.intellij.formatting.FormatTextRanges)

Example 2 with FormatTextRanges

use of com.intellij.formatting.FormatTextRanges in project intellij-community by JetBrains.

the class PostprocessReformattingAspect method normalizeAndReorderPostponedActions.

@NotNull
private List<PostponedAction> normalizeAndReorderPostponedActions(@NotNull Set<PostprocessFormattingTask> rangesToProcess, @NotNull Document document) {
    final List<PostprocessFormattingTask> freeFormattingActions = new ArrayList<>();
    final List<ReindentTask> indentActions = new ArrayList<>();
    PostprocessFormattingTask accumulatedTask = null;
    Iterator<PostprocessFormattingTask> iterator = rangesToProcess.iterator();
    while (iterator.hasNext()) {
        final PostprocessFormattingTask currentTask = iterator.next();
        if (accumulatedTask == null) {
            accumulatedTask = currentTask;
            iterator.remove();
        } else if (accumulatedTask.getStartOffset() > currentTask.getEndOffset() || accumulatedTask.getStartOffset() == currentTask.getEndOffset() && !canStickActionsTogether(accumulatedTask, currentTask)) {
            // action can be pushed
            if (accumulatedTask instanceof ReindentTask) {
                indentActions.add((ReindentTask) accumulatedTask);
            } else {
                freeFormattingActions.add(accumulatedTask);
            }
            accumulatedTask = currentTask;
            iterator.remove();
        } else if (accumulatedTask instanceof ReformatTask && currentTask instanceof ReindentTask) {
            // split accumulated reformat range into two
            if (accumulatedTask.getStartOffset() < currentTask.getStartOffset()) {
                final RangeMarker endOfRange = document.createRangeMarker(accumulatedTask.getStartOffset(), currentTask.getStartOffset());
                // add heading reformat part
                rangesToProcess.add(new ReformatTask(endOfRange));
                // and manage heading whitespace because formatter does not edit it in previous action
                iterator = rangesToProcess.iterator();
                //noinspection StatementWithEmptyBody
                while (iterator.next().getRange() != currentTask.getRange()) ;
            }
            final RangeMarker rangeToProcess = document.createRangeMarker(currentTask.getEndOffset(), accumulatedTask.getEndOffset());
            freeFormattingActions.add(new ReformatWithHeadingWhitespaceTask(rangeToProcess));
            accumulatedTask = currentTask;
            iterator.remove();
        } else {
            if (!(accumulatedTask instanceof ReindentTask)) {
                iterator.remove();
                boolean withLeadingWhitespace = accumulatedTask instanceof ReformatWithHeadingWhitespaceTask;
                if (accumulatedTask instanceof ReformatTask && currentTask instanceof ReformatWithHeadingWhitespaceTask && accumulatedTask.getStartOffset() == currentTask.getStartOffset()) {
                    withLeadingWhitespace = true;
                } else if (accumulatedTask instanceof ReformatWithHeadingWhitespaceTask && currentTask instanceof ReformatTask && accumulatedTask.getStartOffset() < currentTask.getStartOffset()) {
                    withLeadingWhitespace = false;
                }
                int newStart = Math.min(accumulatedTask.getStartOffset(), currentTask.getStartOffset());
                int newEnd = Math.max(accumulatedTask.getEndOffset(), currentTask.getEndOffset());
                RangeMarker rangeMarker;
                if (accumulatedTask.getStartOffset() == newStart && accumulatedTask.getEndOffset() == newEnd) {
                    rangeMarker = accumulatedTask.getRange();
                } else if (currentTask.getStartOffset() == newStart && currentTask.getEndOffset() == newEnd) {
                    rangeMarker = currentTask.getRange();
                } else {
                    rangeMarker = document.createRangeMarker(newStart, newEnd);
                }
                if (withLeadingWhitespace) {
                    accumulatedTask = new ReformatWithHeadingWhitespaceTask(rangeMarker);
                } else {
                    accumulatedTask = new ReformatTask(rangeMarker);
                }
            } else if (currentTask instanceof ReindentTask) {
                iterator.remove();
            }
        // TODO[ik]: need to be fixed to correctly process indent inside indent
        }
    }
    if (accumulatedTask != null) {
        if (accumulatedTask instanceof ReindentTask) {
            indentActions.add((ReindentTask) accumulatedTask);
        } else {
            freeFormattingActions.add(accumulatedTask);
        }
    }
    final List<PostponedAction> result = new ArrayList<>();
    Collections.reverse(freeFormattingActions);
    Collections.reverse(indentActions);
    if (!freeFormattingActions.isEmpty()) {
        FormatTextRanges ranges = new FormatTextRanges();
        for (PostprocessFormattingTask action : freeFormattingActions) {
            TextRange range = TextRange.create(action);
            ranges.add(range, action instanceof ReformatWithHeadingWhitespaceTask);
        }
        result.add(new ReformatRangesAction(ranges));
    }
    if (!indentActions.isEmpty()) {
        ReindentRangesAction reindentRangesAction = new ReindentRangesAction();
        for (ReindentTask action : indentActions) {
            reindentRangesAction.add(action.getRange(), action.getOldIndent());
        }
        result.add(reindentRangesAction);
    }
    return result;
}
Also used : RangeMarker(com.intellij.openapi.editor.RangeMarker) FormatTextRanges(com.intellij.formatting.FormatTextRanges) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

FormatTextRanges (com.intellij.formatting.FormatTextRanges)2 RangeMarker (com.intellij.openapi.editor.RangeMarker)1 TextRange (com.intellij.openapi.util.TextRange)1 CodeFormatterFacade (com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade)1 NotNull (org.jetbrains.annotations.NotNull)1