Navigatable custom regions in XML/HTML structure view [IDEA-CR-16020]

This commit is contained in:
Rustam Vishnyakov
2016-11-22 19:01:18 +03:00
parent 5d70ea9fe7
commit e72f31728d
4 changed files with 38 additions and 3 deletions
@@ -212,6 +212,10 @@ public abstract class CustomFoldingBuilder extends FoldingBuilderEx implements P
return node.getPsi() instanceof PsiComment;
}
public final boolean isCustomFoldingCandidate(@NotNull PsiElement element) {
return isCustomFoldingCandidate(element.getNode());
}
/**
* Checks if the node is used as custom folding root. Any custom folding elements inside the root are considered to be at the same level
* even if they are located at different levels of PSI tree. By default the method returns true if the node has any child elements
@@ -17,7 +17,8 @@ package com.intellij.ide.structureView.customRegions;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.lang.ASTNode;
import com.intellij.lang.folding.CustomFoldingProvider;
import com.intellij.lang.Language;
import com.intellij.lang.folding.*;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.util.containers.ContainerUtil;
@@ -130,6 +131,22 @@ public class CustomRegionStructureUtil {
}
private static boolean isCustomRegionCommentCandidate(@NotNull PsiElement element) {
return element instanceof PsiComment && !element.textContains('\n');
Language language = element.getLanguage();
if (!Language.ANY.is(language)) {
final FoldingBuilder foldingBuilder = LanguageFolding.INSTANCE.forLanguage(language);
if (foldingBuilder instanceof CustomFoldingBuilder) {
return ((CustomFoldingBuilder)foldingBuilder).isCustomFoldingCandidate(element);
}
else if (foldingBuilder instanceof CompositeFoldingBuilder) {
for (FoldingBuilder simpleBuilder : ((CompositeFoldingBuilder)foldingBuilder).getAllBuilders()) {
if (simpleBuilder instanceof CustomFoldingBuilder) {
if (((CustomFoldingBuilder)simpleBuilder).isCustomFoldingCandidate(element)) {
return true;
}
}
}
}
}
return false;
}
}
@@ -152,4 +152,8 @@ public class CustomRegionTreeElement implements StructureViewTreeElement {
return myParent;
}
@Override
public String toString() {
return "Region '" + myProvider.getPlaceholderText(myStartElement.getText()) + "'";
}
}
@@ -83,8 +83,18 @@ public class XmlTokenImpl extends LeafPsiElement implements XmlToken, Navigatabl
return super.getReferences();
}
@Override
public PsiElement getNavigationElement() {
if (getTokenType() == XmlTokenType.XML_COMMENT_CHARACTERS) {
PsiElement parent = this.getParent();
return parent != null ? parent : this;
}
return super.getNavigationElement();
}
@Override
public boolean canNavigate() {
return getTokenType() == XmlTokenType.XML_NAME && PsiNavigationSupport.getInstance().canNavigate(this);
return getTokenType() == XmlTokenType.XML_NAME && PsiNavigationSupport.getInstance().canNavigate(this) ||
getTokenType() == XmlTokenType.XML_COMMENT_CHARACTERS; // Custom regions
}
}