package com.simpleplugin; import com.intellij.lang.ASTNode; import com.intellij.lang.folding.*; import com.intellij.openapi.editor.*; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.simpleplugin.psi.SimpleProperty; import org.jetbrains.annotations.*; import java.util.*; public class SimpleFoldingBuilder extends FoldingBuilderEx implements DumbAware { @NotNull @Override public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) { FoldingGroup group = FoldingGroup.newGroup("simple"); List descriptors = new ArrayList(); Collection literalExpressions = PsiTreeUtil.findChildrenOfType(root, PsiLiteralExpression.class); for (final PsiLiteralExpression literalExpression : literalExpressions) { String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null; if (value != null && value.startsWith("simple:")) { Project project = literalExpression.getProject(); String key = value.substring(7); final List properties = SimpleUtil.findProperties(project, key); if (properties.size() == 1) { descriptors.add(new FoldingDescriptor(literalExpression.getNode(), new TextRange(literalExpression.getTextRange().getStartOffset() + 1, literalExpression.getTextRange().getEndOffset() - 1), group) { @Nullable @Override public String getPlaceholderText() { // IMPORTANT: keys can come with no values, so a test for null is needed // IMPORTANT: Convert embedded \n to backslash n, so that the string will look like it has LF embedded // in it and embedded " to escaped " String valueOf = properties.get(0).getValue(); return valueOf == null ? "" : valueOf.replaceAll("\n", "\\n").replaceAll("\"", "\\\\\""); } }); } } } return descriptors.toArray(new FoldingDescriptor[descriptors.size()]); } @Nullable @Override public String getPlaceholderText(@NotNull ASTNode node) { String retTxt = "..."; if ( node.getPsi() instanceof PsiLiteralExpression ) { PsiLiteralExpression nodeElement = (PsiLiteralExpression) node.getPsi(); String key = ((String) nodeElement.getValue()).substring("simple:".length()); final List< SimpleProperty > properties = SimpleUtil.findProperties(nodeElement.getProject(), key); String place = properties.get(0).getValue(); // IMPORTANT: keys can come with no values, so a test for null is needed // IMPORTANT: Convert embedded \n to backslash n, so that the string will look // like it has LF embedded in it and embedded " to escaped " return place == null ? retTxt : place.replaceAll("\n", "\\n").replaceAll("\"", "\\\\\""); } return retTxt; } @Override public boolean isCollapsedByDefault(@NotNull ASTNode node) { return true; } }