Code folding not working

Answered

Hi everyone,

I would like to fold an annotation that spans multiple lines. I extended FoldingBuilderEx, and registered my class in plugins.xml. Here is my code:

public class AnnotationFolderBuilder extends FoldingBuilderEx {
static final private List<String> COCONUT_ANNOTATIONS = Arrays.asList(
"@LocationAnnotation",
"@NetworkAnnotation"
);

private FoldingGroup group = FoldingGroup.newGroup("annotationFoldGroup");

@NotNull
@Override
public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) {
List<FoldingDescriptor> descriptors = new ArrayList<FoldingDescriptor>();
Collection<PsiAnnotation> annotations =
PsiTreeUtil.findChildrenOfType(root, PsiAnnotation.class);

for(final PsiAnnotation annotation : annotations) {
if(isCoconutAnnotation(annotation.getText())) {
descriptors.add(createFoldingDescriptor(annotation));
}
}

return descriptors.toArray(new FoldingDescriptor[descriptors.size()]);
}

private boolean isCoconutAnnotation(String annotationText) {
for(final String annotation : COCONUT_ANNOTATIONS) {
if(annotationText.contains(annotation)) {
return true;
}
}

return false;
}

private FoldingDescriptor createFoldingDescriptor(PsiAnnotation annotation) {
System.out.println(annotation.getText() + " has range " +
annotation.getTextRange().getStartOffset() + " - " +
annotation.getTextRange().getEndOffset());
return new FoldingDescriptor(annotation.getNode(),
new TextRange(annotation.getTextRange().getStartOffset() + 4,
annotation.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 "
return "\\n".replaceAll("\"", "\\\\\"");
}
};
}

@Nullable
@Override
public String getPlaceholderText(@NotNull ASTNode node) {
return "...";
}

@Override
public boolean isCollapsedByDefault(@NotNull ASTNode node) {
return true;
}
}

The annotation is not folding or doing anything in the test program. Any help or further explanation of how FoldingBuilders work would be great (ex: why are there two getPlaceHolderTexts?)

Thanks!

0
3 comments
Avatar
Permanently deleted user

Look at `annotation.getText()`.  What is it returning?

At a guess, if your annotation is a multi-line annotation, the PSI probably has multiple children and the `getText()` is returning the value of all children combined; it won't match anything in the `COCONUT_ANNOTATIONS` array.

It will be much easier to tell what is going on if you post an example annotation, and the PSI structure of the annotation itself.  (Copy and paste the node from the PSI Viewer.  See https://www.jetbrains.com/help/idea/psi-viewer.html for docs.)

1

Why are there two getPlaceHolderText() - see com.intellij.lang.folding.FoldingDescriptor#getPlaceholderText

 

Please try passing in your Annotation instead of manually (and possibly incorrect) built TextRange in FoldingDescriptor CTOR. There's plenty of usages in IJ Community sources.

1
Avatar
Permanently deleted user

Hey fellas,

Thanks both of you for your comments. They were really helpful! I am now able to get the annotations to fold.

My FoldingDescriptor has since been changed to this:

FoldingDescriptor(annotation.getNode(), annotation.getTextRange())

 

0

Please sign in to leave a comment.