From e72f31728d810a416ce0a65f1e7ec68ef1ca0098 Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Tue, 22 Nov 2016 18:24:35 +0300 Subject: [PATCH] Navigatable custom regions in XML/HTML structure view [IDEA-CR-16020] --- .../lang/folding/CustomFoldingBuilder.java | 4 ++++ .../CustomRegionStructureUtil.java | 21 +++++++++++++++++-- .../CustomRegionTreeElement.java | 4 ++++ .../psi/impl/source/xml/XmlTokenImpl.java | 12 ++++++++++- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/platform/core-api/src/com/intellij/lang/folding/CustomFoldingBuilder.java b/platform/core-api/src/com/intellij/lang/folding/CustomFoldingBuilder.java index ac748e948e05..be3fd5f63435 100644 --- a/platform/core-api/src/com/intellij/lang/folding/CustomFoldingBuilder.java +++ b/platform/core-api/src/com/intellij/lang/folding/CustomFoldingBuilder.java @@ -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 diff --git a/platform/structure-view-impl/src/com/intellij/ide/structureView/customRegions/CustomRegionStructureUtil.java b/platform/structure-view-impl/src/com/intellij/ide/structureView/customRegions/CustomRegionStructureUtil.java index 19d12c786aa3..3636d11e875f 100644 --- a/platform/structure-view-impl/src/com/intellij/ide/structureView/customRegions/CustomRegionStructureUtil.java +++ b/platform/structure-view-impl/src/com/intellij/ide/structureView/customRegions/CustomRegionStructureUtil.java @@ -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; } } diff --git a/platform/structure-view-impl/src/com/intellij/ide/structureView/customRegions/CustomRegionTreeElement.java b/platform/structure-view-impl/src/com/intellij/ide/structureView/customRegions/CustomRegionTreeElement.java index f0024608e3f8..211db45a7494 100644 --- a/platform/structure-view-impl/src/com/intellij/ide/structureView/customRegions/CustomRegionTreeElement.java +++ b/platform/structure-view-impl/src/com/intellij/ide/structureView/customRegions/CustomRegionTreeElement.java @@ -152,4 +152,8 @@ public class CustomRegionTreeElement implements StructureViewTreeElement { return myParent; } + @Override + public String toString() { + return "Region '" + myProvider.getPlaceholderText(myStartElement.getText()) + "'"; + } } diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTokenImpl.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTokenImpl.java index f22d4af60d96..f3e9c52fc226 100644 --- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTokenImpl.java +++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTokenImpl.java @@ -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 } }