Search in sources :

Example 11 with FoldingDescriptor

use of com.intellij.lang.folding.FoldingDescriptor in project intellij-community by JetBrains.

the class DocumentFoldingInfo method setToEditor.

@Override
public void setToEditor(@NotNull final Editor editor) {
    assertDispatchThread();
    final PsiManager psiManager = PsiManager.getInstance(myProject);
    if (psiManager.isDisposed())
        return;
    if (!myFile.isValid())
        return;
    final PsiFile psiFile = psiManager.findFile(myFile);
    if (psiFile == null)
        return;
    if (!mySerializedElements.isEmpty()) {
        // Restore postponed state
        assert myPsiElements.isEmpty() : "Sequential deserialization";
        for (SerializedPsiElement entry : mySerializedElements) {
            PsiElement restoredElement = FoldingPolicy.restoreBySignature(psiFile, entry.mySerializedElement);
            if (restoredElement != null && restoredElement.isValid()) {
                myPsiElements.add(SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(restoredElement));
                restoredElement.putUserData(FOLDING_INFO_KEY, entry.myFoldingInfo);
            }
        }
        mySerializedElements.clear();
    }
    Map<PsiElement, FoldingDescriptor> ranges = null;
    for (SmartPsiElementPointer<PsiElement> ptr : myPsiElements) {
        PsiElement element = ptr.getElement();
        if (element == null || !element.isValid()) {
            continue;
        }
        if (ranges == null) {
            ranges = buildRanges(editor, psiFile);
        }
        FoldingDescriptor descriptor = ranges.get(element);
        if (descriptor == null) {
            continue;
        }
        TextRange range = descriptor.getRange();
        FoldRegion region = FoldingUtil.findFoldRegion(editor, range.getStartOffset(), range.getEndOffset());
        if (region != null) {
            FoldingInfo fi = element.getUserData(FOLDING_INFO_KEY);
            boolean state = fi != null && fi.expanded;
            region.setExpanded(state);
        }
    }
    for (RangeMarker marker : myRangeMarkers) {
        if (!marker.isValid() || marker.getStartOffset() == marker.getEndOffset()) {
            continue;
        }
        FoldRegion region = FoldingUtil.findFoldRegion(editor, marker.getStartOffset(), marker.getEndOffset());
        FoldingInfo info = marker.getUserData(FOLDING_INFO_KEY);
        if (region == null) {
            if (info != null) {
                region = editor.getFoldingModel().addFoldRegion(marker.getStartOffset(), marker.getEndOffset(), info.placeHolder);
            }
            if (region == null) {
                return;
            }
        }
        boolean state = info != null && info.expanded;
        region.setExpanded(state);
    }
}
Also used : FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) FoldRegion(com.intellij.openapi.editor.FoldRegion) RangeMarker(com.intellij.openapi.editor.RangeMarker)

Example 12 with FoldingDescriptor

use of com.intellij.lang.folding.FoldingDescriptor in project intellij-community by JetBrains.

the class CustomFileTypeFoldingBuilder method buildBraceMatcherBasedFolding.

public static void buildBraceMatcherBasedFolding(List<FoldingDescriptor> descriptors, PsiElement root, Document document, SyntaxHighlighter highlighter) {
    LexerEditorHighlighter editorHighlighter = new LexerEditorHighlighter(highlighter, EditorColorsManager.getInstance().getGlobalScheme());
    editorHighlighter.setText(document.getText());
    FileType fileType = root.getContainingFile().getFileType();
    BraceMatcher braceMatcher = BraceMatchingUtil.getBraceMatcher(fileType, root.getLanguage());
    TextRange totalRange = root.getTextRange();
    final HighlighterIterator iterator = editorHighlighter.createIterator(totalRange.getStartOffset());
    final LinkedList<Trinity<Integer, Integer, IElementType>> stack = new LinkedList<>();
    String editorText = document.getText();
    while (!iterator.atEnd() && iterator.getStart() < totalRange.getEndOffset()) {
        final Trinity<Integer, Integer, IElementType> last;
        if (braceMatcher.isLBraceToken(iterator, editorText, fileType) && braceMatcher.isStructuralBrace(iterator, editorText, fileType)) {
            stack.addLast(Trinity.create(iterator.getStart(), iterator.getEnd(), iterator.getTokenType()));
        } else if (braceMatcher.isRBraceToken(iterator, editorText, fileType) && braceMatcher.isStructuralBrace(iterator, editorText, fileType) && !stack.isEmpty() && braceMatcher.isPairBraces((last = stack.getLast()).third, iterator.getTokenType())) {
            stack.removeLast();
            TextRange range = new TextRange(last.first, iterator.getEnd());
            if (StringUtil.countChars(document.getText(range), '\n') >= 3) {
                descriptors.add(new FoldingDescriptor(root, range));
            }
        }
        iterator.advance();
    }
}
Also used : FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) BraceMatcher(com.intellij.codeInsight.highlighting.BraceMatcher) Trinity(com.intellij.openapi.util.Trinity) TextRange(com.intellij.openapi.util.TextRange) LexerEditorHighlighter(com.intellij.openapi.editor.ex.util.LexerEditorHighlighter) LinkedList(java.util.LinkedList) IElementType(com.intellij.psi.tree.IElementType) FileType(com.intellij.openapi.fileTypes.FileType) CustomSyntaxTableFileType(com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType) HighlighterIterator(com.intellij.openapi.editor.highlighter.HighlighterIterator)

Example 13 with FoldingDescriptor

use of com.intellij.lang.folding.FoldingDescriptor in project intellij-community by JetBrains.

the class IndentationFoldingBuilder method collectDescriptors.

private void collectDescriptors(@NotNull final ASTNode node, @NotNull final List<FoldingDescriptor> descriptors) {
    final Queue<ASTNode> toProcess = new LinkedList<>();
    toProcess.add(node);
    while (!toProcess.isEmpty()) {
        final ASTNode current = toProcess.remove();
        if (current.getTreeParent() != null && current.getTextLength() > 1 && myTokenSet.contains(current.getElementType())) {
            descriptors.add(new FoldingDescriptor(current, current.getTextRange()));
        }
        for (ASTNode child = current.getFirstChildNode(); child != null; child = child.getTreeNext()) {
            toProcess.add(child);
        }
    }
}
Also used : FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) ASTNode(com.intellij.lang.ASTNode) LinkedList(java.util.LinkedList)

Example 14 with FoldingDescriptor

use of com.intellij.lang.folding.FoldingDescriptor in project intellij-community by JetBrains.

the class JavaFoldingBuilderBase method addCommentFolds.

/**
   * We want to allow to fold subsequent single line comments like
   * <pre>
   *     // this is comment line 1
   *     // this is comment line 2
   * </pre>
   *
   * @param comment             comment to check
   * @param processedComments   set that contains already processed elements. It is necessary because we process all elements of
   *                            the PSI tree, hence, this method may be called for both comments from the example above. However,
   *                            we want to create fold region during the first comment processing, put second comment to it and
   *                            skip processing when current method is called for the second element
   * @param foldElements        fold descriptors holder to store newly created descriptor (if any)
   */
private static void addCommentFolds(@NotNull PsiComment comment, @NotNull Set<PsiElement> processedComments, @NotNull List<FoldingDescriptor> foldElements) {
    if (processedComments.contains(comment) || comment.getTokenType() != JavaTokenType.END_OF_LINE_COMMENT) {
        return;
    }
    PsiElement end = null;
    boolean containsCustomRegionMarker = isCustomRegionElement(comment);
    for (PsiElement current = comment.getNextSibling(); current != null; current = current.getNextSibling()) {
        ASTNode node = current.getNode();
        if (node == null) {
            break;
        }
        IElementType elementType = node.getElementType();
        if (elementType == JavaTokenType.END_OF_LINE_COMMENT) {
            end = current;
            // We don't want to process, say, the second comment in case of three subsequent comments when it's being examined
            // during all elements traversal. I.e. we expect to start from the first comment and grab as many subsequent
            // comments as possible during the single iteration.
            processedComments.add(current);
            containsCustomRegionMarker |= isCustomRegionElement(current);
            continue;
        }
        if (elementType == TokenType.WHITE_SPACE) {
            continue;
        }
        break;
    }
    if (end != null && !containsCustomRegionMarker) {
        foldElements.add(new FoldingDescriptor(comment, new TextRange(comment.getTextRange().getStartOffset(), end.getTextRange().getEndOffset())));
    }
}
Also used : IElementType(com.intellij.psi.tree.IElementType) FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) NamedFoldingDescriptor(com.intellij.lang.folding.NamedFoldingDescriptor) ASTNode(com.intellij.lang.ASTNode) TextRange(com.intellij.openapi.util.TextRange) UnfairTextRange(com.intellij.openapi.util.UnfairTextRange)

Example 15 with FoldingDescriptor

use of com.intellij.lang.folding.FoldingDescriptor in project intellij-community by JetBrains.

the class GroovyFoldingBuilder method addFoldingForStrings.

private static void addFoldingForStrings(List<FoldingDescriptor> descriptors, ASTNode node) {
    if (!isMultiLineStringLiteral(node))
        return;
    if (!node.getElementType().equals(GroovyElementTypes.GSTRING) && !node.getElementType().equals(GroovyElementTypes.REGEX)) {
        descriptors.add(new FoldingDescriptor(node, node.getTextRange()));
        return;
    }
    final GrString grString = (GrString) node.getPsi();
    if (grString == null)
        return;
    final GrStringInjection[] injections = grString.getInjections();
    if (injections.length == 0) {
        descriptors.add(new FoldingDescriptor(node, node.getTextRange()));
        return;
    }
    final String start_quote = GrStringUtil.getStartQuote(node.getText());
    final String end_quote = GrStringUtil.getEndQuote(node.getText());
    final FoldingGroup group = FoldingGroup.newGroup("GString");
    final TextRange nodeRange = node.getTextRange();
    int startOffset = nodeRange.getStartOffset();
    GrStringInjection injection = injections[0];
    TextRange injectionRange = injection.getTextRange();
    if (startOffset + 1 < injectionRange.getStartOffset()) {
        descriptors.add(new NamedFoldingDescriptor(node, startOffset, injectionRange.getStartOffset(), group, start_quote));
    }
    final String placeholder = " ";
    startOffset = injectionRange.getEndOffset();
    for (int i = 1; i < injections.length; i++) {
        injection = injections[i];
        injectionRange = injection.getTextRange();
        final int endOffset = injectionRange.getStartOffset();
        if (endOffset - startOffset >= 2) {
            descriptors.add(new NamedFoldingDescriptor(injection.getNode().getTreePrev(), startOffset, endOffset, group, placeholder));
        }
        startOffset = injectionRange.getEndOffset();
    }
    if (startOffset + 1 < nodeRange.getEndOffset()) {
        descriptors.add(new NamedFoldingDescriptor(node.getLastChildNode(), startOffset, nodeRange.getEndOffset(), group, end_quote));
    }
}
Also used : FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) NamedFoldingDescriptor(com.intellij.lang.folding.NamedFoldingDescriptor) FoldingGroup(com.intellij.openapi.editor.FoldingGroup) NamedFoldingDescriptor(com.intellij.lang.folding.NamedFoldingDescriptor) GrString(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrString) TextRange(com.intellij.openapi.util.TextRange) GrString(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrString) GrStringInjection(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringInjection)

Aggregations

FoldingDescriptor (com.intellij.lang.folding.FoldingDescriptor)39 TextRange (com.intellij.openapi.util.TextRange)24 ASTNode (com.intellij.lang.ASTNode)17 PsiElement (com.intellij.psi.PsiElement)12 IElementType (com.intellij.psi.tree.IElementType)9 NamedFoldingDescriptor (com.intellij.lang.folding.NamedFoldingDescriptor)8 UnfairTextRange (com.intellij.openapi.util.UnfairTextRange)6 PsiComment (com.intellij.psi.PsiComment)5 PsiWhiteSpace (com.intellij.psi.PsiWhiteSpace)5 FoldingGroup (com.intellij.openapi.editor.FoldingGroup)4 NotNull (org.jetbrains.annotations.NotNull)4 FoldRegion (com.intellij.openapi.editor.FoldRegion)3 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)3 LinkedList (java.util.LinkedList)3 HbBlockWrapper (com.dmarcotte.handlebars.psi.HbBlockWrapper)2 FoldingBuilder (com.intellij.lang.folding.FoldingBuilder)2 ArrayList (java.util.ArrayList)2 Nullable (org.jetbrains.annotations.Nullable)2 LocalResourceRepository (com.android.tools.idea.res.LocalResourceRepository)1 BraceMatcher (com.intellij.codeInsight.highlighting.BraceMatcher)1