Search in sources :

Example 11 with FoldingGroup

use of com.intellij.openapi.editor.FoldingGroup in project intellij-community by JetBrains.

the class UpdateFoldRegionsOperation method run.

@Override
public void run() {
    EditorFoldingInfo info = EditorFoldingInfo.get(myEditor);
    FoldingModelEx foldingModel = (FoldingModelEx) myEditor.getFoldingModel();
    Map<TextRange, Boolean> rangeToExpandStatusMap = new THashMap<>();
    // FoldingUpdate caches instances of our object, so they must be immutable.
    FoldingUpdate.FoldingMap elementsToFold = new FoldingUpdate.FoldingMap(myElementsToFoldMap);
    removeInvalidRegions(info, foldingModel, elementsToFold, rangeToExpandStatusMap);
    Map<FoldRegion, Boolean> shouldExpand = new THashMap<>();
    Map<FoldingGroup, Boolean> groupExpand = new THashMap<>();
    List<FoldRegion> newRegions = addNewRegions(info, foldingModel, elementsToFold, rangeToExpandStatusMap, shouldExpand, groupExpand);
    applyExpandStatus(newRegions, shouldExpand, groupExpand);
    foldingModel.clearDocumentRangesModificationStatus();
}
Also used : FoldingGroup(com.intellij.openapi.editor.FoldingGroup) FoldRegion(com.intellij.openapi.editor.FoldRegion) TextRange(com.intellij.openapi.util.TextRange) FoldingModelEx(com.intellij.openapi.editor.ex.FoldingModelEx) THashMap(gnu.trove.THashMap)

Example 12 with FoldingGroup

use of com.intellij.openapi.editor.FoldingGroup in project intellij-elixir by KronicDeth.

the class Builder method buildFoldRegions.

/*
     * Instance Methods
     */
/**
     * Builds the folding regions for the specified node in the AST tree and its children.
     *
     * @param root     the element for which folding is requested.
     * @param document the document for which folding is built. Can be used to retrieve line
     *                 numbers for folding regions.
     * @param quick    whether the result should be provided as soon as possible. Is true, when
     *                 an editor is opened and we need to auto-fold something immediately, like Java imports.
     *                 If true, one should perform no reference resolving and avoid complex checks if possible.
     * @return the array of folding descriptors.
     */
@NotNull
@Override
public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, final boolean quick) {
    final List<FoldingDescriptor> foldingDescriptorList = new ArrayList<FoldingDescriptor>();
    PsiTreeUtil.processElements(root, new PsiElementProcessor() {

        private Map<String, FoldingGroup> foldingGroupByModuleAttributeName = new HashMap<String, FoldingGroup>();

        /*
                     *
                     * Instance Methods
                     *
                     */
        /*
                     * Public Instance Methods
                     */
        @Override
        public boolean execute(@NotNull PsiElement element) {
            boolean keepProcessing = true;
            if (element instanceof AtNonNumericOperation) {
                keepProcessing = execute((AtNonNumericOperation) element);
            } else if (element instanceof AtUnqualifiedNoParenthesesCall) {
                keepProcessing = execute((AtUnqualifiedNoParenthesesCall) element);
            } else if (element instanceof ElixirDoBlock) {
                keepProcessing = execute((ElixirDoBlock) element);
            } else if (element instanceof ElixirStabOperation) {
                keepProcessing = execute((ElixirStabOperation) element);
            } else if (element instanceof Call) {
                keepProcessing = execute((Call) element);
            }
            return keepProcessing;
        }

        /*
                     * Private Instance Methods
                     */
        private boolean execute(@NotNull AtNonNumericOperation atNonNumericOperation) {
            boolean keepProcessing = true;
            if (!quick) {
                keepProcessing = slowExecute(atNonNumericOperation);
            }
            return keepProcessing;
        }

        private boolean execute(@NotNull AtUnqualifiedNoParenthesesCall atUnqualifiedNoParenthesesCall) {
            String moduleAttributeName = moduleAttributeName(atUnqualifiedNoParenthesesCall);
            String name = moduleAttributeName.substring(1);
            if (ModuleAttribute.isDocumentationName(name)) {
                ElixirNoParenthesesOneArgument noParenthesesOneArgument = atUnqualifiedNoParenthesesCall.getNoParenthesesOneArgument();
                foldingDescriptorList.add(new NamedFoldingDescriptor(noParenthesesOneArgument.getNode(), noParenthesesOneArgument.getTextRange(), null, "\"...\""));
            } else if (ModuleAttribute.isTypeName(name)) {
                ElixirNoParenthesesOneArgument noParenthesesOneArgument = atUnqualifiedNoParenthesesCall.getNoParenthesesOneArgument();
                PsiElement[] children = noParenthesesOneArgument.getChildren();
                if (children.length == 1) {
                    PsiElement child = children[0];
                    if (child instanceof Type) {
                        Type type = (Type) child;
                        PsiElement rightOperand = Normalized.rightOperand(type);
                        if (rightOperand != null) {
                            foldingDescriptorList.add(new NamedFoldingDescriptor(rightOperand.getNode(), rightOperand.getTextRange(), null, "..."));
                        }
                    }
                }
            }
            return true;
        }

        private boolean execute(@NotNull Call call) {
            for (String resolvedFunctionName : RESOLVED_FUNCTION_NAMES) {
                if (call.isCalling(KERNEL, resolvedFunctionName)) {
                    if (isFirstInGroup(call, KERNEL, resolvedFunctionName)) {
                        Call last = lastInGroup(call, KERNEL, resolvedFunctionName);
                        PsiElement[] finalArguments = finalArguments(call);
                        if (finalArguments != null && finalArguments.length >= 1) {
                            TextRange textRange = new TextRange(finalArguments[0].getTextOffset(), last.getTextRange().getEndOffset());
                            foldingDescriptorList.add(new NamedFoldingDescriptor(call.getParent().getNode(), textRange, null, "..."));
                        }
                    }
                }
            }
            return true;
        }

        private boolean execute(@NotNull ElixirDoBlock doBlock) {
            foldingDescriptorList.add(new FoldingDescriptor(doBlock, doBlock.getTextRange()));
            return true;
        }

        private boolean execute(@NotNull ElixirStabOperation stabOperation) {
            int startOffset = stabOperation.operator().getTextOffset();
            int endOffset = stabOperation.getTextRange().getEndOffset();
            TextRange textRange = new TextRange(startOffset, endOffset);
            foldingDescriptorList.add(new FoldingDescriptor(stabOperation, textRange));
            return true;
        }

        private boolean isFirstInGroup(@NotNull Call call, @NotNull String resolvedModuleName, @NotNull String resolvedFunctionName) {
            PsiElement previousSiblingExpression = previousSiblingExpression(call);
            boolean first = true;
            if (previousSiblingExpression instanceof Call) {
                Call previousSiblingExpressionCall = (Call) previousSiblingExpression;
                first = !previousSiblingExpressionCall.isCalling(resolvedModuleName, resolvedFunctionName);
            }
            return first;
        }

        @NotNull
        private Call lastInGroup(@NotNull Call first, @NotNull String resolvedModuleName, @NotNull String resolvedFunctionName) {
            PsiElement expression = first;
            Call last = first;
            while (true) {
                expression = nextSiblingExpression(expression);
                if (expression instanceof Call) {
                    Call call = (Call) expression;
                    if (call.isCalling(resolvedModuleName, resolvedFunctionName)) {
                        last = call;
                        continue;
                    }
                }
                break;
            }
            return last;
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation) {
            boolean keepProcessing = true;
            PsiReference reference = atNonNumericOperation.getReference();
            if (reference != null) {
                keepProcessing = slowExecute(atNonNumericOperation, reference);
            }
            return keepProcessing;
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull final AtUnqualifiedNoParenthesesCall atUnqualifiedNoParenthesesCall) {
            return slowExecute(atNonNumericOperation, atUnqualifiedNoParenthesesCall, atUnqualifiedNoParenthesesCall.getNoParenthesesOneArgument().getText());
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull PsiElement target) {
            boolean keepProcessing = true;
            if (target instanceof AtUnqualifiedNoParenthesesCall) {
                keepProcessing = slowExecute(atNonNumericOperation, (AtUnqualifiedNoParenthesesCall) target);
            } else if (target instanceof QualifiableAlias) {
                keepProcessing = slowExecute(atNonNumericOperation, (QualifiableAlias) target);
            }
            return keepProcessing;
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull PsiReference reference) {
            PsiElement target = reference.resolve();
            boolean keepProcessing = true;
            if (target != null) {
                keepProcessing = slowExecute(atNonNumericOperation, target);
            }
            return keepProcessing;
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull final QualifiableAlias qualifiableAlias) {
            return slowExecute(atNonNumericOperation, qualifiableAlias, qualifiableAlias.getName());
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull PsiElement element, @Nullable final String placeHolderText) {
            String moduleAttributeName = atNonNumericOperation.moduleAttributeName();
            FoldingGroup foldingGroup = foldingGroupByModuleAttributeName.get(moduleAttributeName);
            if (foldingGroup == null) {
                foldingGroup = FoldingGroup.newGroup(moduleAttributeName);
                foldingGroupByModuleAttributeName.put(moduleAttributeName, foldingGroup);
            }
            foldingDescriptorList.add(new FoldingDescriptor(atNonNumericOperation.getNode(), atNonNumericOperation.getTextRange(), foldingGroup, Collections.<Object>singleton(element)) {

                @Nullable
                @Override
                public String getPlaceholderText() {
                    return placeHolderText;
                }
            });
            return true;
        }
    });
    return foldingDescriptorList.toArray(new FoldingDescriptor[foldingDescriptorList.size()]);
}
Also used : Call(org.elixir_lang.psi.call.Call) NamedFoldingDescriptor(com.intellij.lang.folding.NamedFoldingDescriptor) FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) FoldingGroup(com.intellij.openapi.editor.FoldingGroup) PsiReference(com.intellij.psi.PsiReference) TextRange(com.intellij.openapi.util.TextRange) NotNull(org.jetbrains.annotations.NotNull) PsiElementProcessor(com.intellij.psi.search.PsiElementProcessor) Type(org.elixir_lang.psi.operation.Type) NamedFoldingDescriptor(com.intellij.lang.folding.NamedFoldingDescriptor) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

FoldingGroup (com.intellij.openapi.editor.FoldingGroup)12 FoldingDescriptor (com.intellij.lang.folding.FoldingDescriptor)6 NamedFoldingDescriptor (com.intellij.lang.folding.NamedFoldingDescriptor)5 FoldRegion (com.intellij.openapi.editor.FoldRegion)5 TextRange (com.intellij.openapi.util.TextRange)5 NotNull (org.jetbrains.annotations.NotNull)4 PsiElement (com.intellij.psi.PsiElement)3 ArrayList (java.util.ArrayList)3 PsiReference (com.intellij.psi.PsiReference)2 StringLiteralExpression (com.jetbrains.php.lang.psi.elements.StringLiteralExpression)2 Nullable (org.jetbrains.annotations.Nullable)2 Document (com.intellij.openapi.editor.Document)1 EditorEx (com.intellij.openapi.editor.ex.EditorEx)1 FoldingModelEx (com.intellij.openapi.editor.ex.FoldingModelEx)1 IndexNotReadyException (com.intellij.openapi.project.IndexNotReadyException)1 Project (com.intellij.openapi.project.Project)1 SmartPointerManager (com.intellij.psi.SmartPointerManager)1 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)1 PsiElementProcessor (com.intellij.psi.search.PsiElementProcessor)1 XmlAttributeValue (com.intellij.psi.xml.XmlAttributeValue)1