support custom folding regions for Kotlin
#KT-5207 Fixed
This commit is contained in:
@@ -18,11 +18,12 @@ package org.jetbrains.kotlin.idea
|
|||||||
|
|
||||||
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings
|
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings
|
||||||
import com.intellij.lang.ASTNode
|
import com.intellij.lang.ASTNode
|
||||||
import com.intellij.lang.folding.FoldingBuilderEx
|
import com.intellij.lang.folding.CustomFoldingBuilder
|
||||||
import com.intellij.lang.folding.FoldingDescriptor
|
import com.intellij.lang.folding.FoldingDescriptor
|
||||||
import com.intellij.openapi.editor.Document
|
import com.intellij.openapi.editor.Document
|
||||||
import com.intellij.openapi.project.DumbAware
|
import com.intellij.openapi.project.DumbAware
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
|
import com.intellij.psi.PsiComment
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiWhiteSpace
|
import com.intellij.psi.PsiWhiteSpace
|
||||||
import org.jetbrains.kotlin.JetNodeTypes
|
import org.jetbrains.kotlin.JetNodeTypes
|
||||||
@@ -31,15 +32,13 @@ import org.jetbrains.kotlin.lexer.JetTokens
|
|||||||
import org.jetbrains.kotlin.psi.JetFile
|
import org.jetbrains.kotlin.psi.JetFile
|
||||||
import org.jetbrains.kotlin.psi.JetFunctionLiteral
|
import org.jetbrains.kotlin.psi.JetFunctionLiteral
|
||||||
import org.jetbrains.kotlin.psi.JetImportList
|
import org.jetbrains.kotlin.psi.JetImportList
|
||||||
import java.util.ArrayList
|
|
||||||
|
|
||||||
public class KotlinFoldingBuilder : FoldingBuilderEx(), DumbAware {
|
public class KotlinFoldingBuilder : CustomFoldingBuilder(), DumbAware {
|
||||||
override fun buildFoldRegions(root: PsiElement, document: Document, quick: Boolean): Array<FoldingDescriptor> {
|
override fun buildLanguageFoldRegions(descriptors: MutableList<FoldingDescriptor>,
|
||||||
|
root: PsiElement, document: Document, quick: Boolean) {
|
||||||
if (root !is JetFile) {
|
if (root !is JetFile) {
|
||||||
return FoldingDescriptor.EMPTY
|
return
|
||||||
}
|
}
|
||||||
val descriptors = ArrayList<FoldingDescriptor>()
|
|
||||||
|
|
||||||
val imports = root.getImportDirectives()
|
val imports = root.getImportDirectives()
|
||||||
if (imports.size() > 1) {
|
if (imports.size() > 1) {
|
||||||
val importKeyword = imports.get(0).getFirstChild()
|
val importKeyword = imports.get(0).getFirstChild()
|
||||||
@@ -55,7 +54,6 @@ public class KotlinFoldingBuilder : FoldingBuilderEx(), DumbAware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
appendDescriptors(root.getNode(), document, descriptors)
|
appendDescriptors(root.getNode(), document, descriptors)
|
||||||
return descriptors.copyToArray()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun appendDescriptors(node: ASTNode, document: Document, descriptors: MutableList<FoldingDescriptor>) {
|
private fun appendDescriptors(node: ASTNode, document: Document, descriptors: MutableList<FoldingDescriptor>) {
|
||||||
@@ -96,29 +94,23 @@ public class KotlinFoldingBuilder : FoldingBuilderEx(), DumbAware {
|
|||||||
private fun isOneLine(textRange: TextRange, document: Document) =
|
private fun isOneLine(textRange: TextRange, document: Document) =
|
||||||
document.getLineNumber(textRange.getStartOffset()) == document.getLineNumber(textRange.getEndOffset())
|
document.getLineNumber(textRange.getStartOffset()) == document.getLineNumber(textRange.getEndOffset())
|
||||||
|
|
||||||
override fun getPlaceholderText(node: ASTNode): String? {
|
override fun getLanguagePlaceholderText(node: ASTNode, range: TextRange): String = when {
|
||||||
if (node.getElementType() == JetTokens.BLOCK_COMMENT) {
|
node.getElementType() == JetTokens.BLOCK_COMMENT -> "/.../"
|
||||||
return "/.../"
|
node.getElementType() == KDocTokens.KDOC -> "/**...*/"
|
||||||
}
|
node.getPsi() is JetImportList -> "..."
|
||||||
if (node.getElementType() == KDocTokens.KDOC) {
|
else -> "{...}"
|
||||||
return "/**...*/"
|
|
||||||
}
|
|
||||||
if (node.getPsi() is JetImportList) {
|
|
||||||
return "..."
|
|
||||||
}
|
|
||||||
return "{...}"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isCollapsedByDefault(astNode: ASTNode): Boolean {
|
override fun isRegionCollapsedByDefault(node: ASTNode): Boolean {
|
||||||
val settings = JavaCodeFoldingSettings.getInstance()
|
val settings = JavaCodeFoldingSettings.getInstance()
|
||||||
|
|
||||||
if (astNode.getPsi() is JetImportList) {
|
if (node.getPsi() is JetImportList) {
|
||||||
return settings.isCollapseImports()
|
return settings.isCollapseImports()
|
||||||
}
|
}
|
||||||
|
|
||||||
val type = astNode.getElementType()
|
val type = node.getElementType()
|
||||||
if (type == JetTokens.BLOCK_COMMENT || type == KDocTokens.KDOC) {
|
if (type == JetTokens.BLOCK_COMMENT || type == KDocTokens.KDOC) {
|
||||||
if (isFirstElementInFile(astNode.getPsi())) {
|
if (isFirstElementInFile(node.getPsi())) {
|
||||||
return settings.isCollapseFileHeader()
|
return settings.isCollapseFileHeader()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,6 +118,9 @@ public class KotlinFoldingBuilder : FoldingBuilderEx(), DumbAware {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isCustomFoldingRoot(node: ASTNode)
|
||||||
|
= node.getElementType() == JetNodeTypes.BLOCK || node.getElementType() == JetNodeTypes.CLASS_BODY
|
||||||
|
|
||||||
private fun isFirstElementInFile(element: PsiElement): Boolean {
|
private fun isFirstElementInFile(element: PsiElement): Boolean {
|
||||||
val parent = element.getParent()
|
val parent = element.getParent()
|
||||||
if (parent is JetFile) {
|
if (parent is JetFile) {
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
class Foo <fold text='{...}' expand='true'>{
|
||||||
|
<fold text='Methods' expand='true'>// <editor-fold desc="Methods">
|
||||||
|
fun foo() {}
|
||||||
|
|
||||||
|
fun bar() <fold text='{...}' expand='true'>{
|
||||||
|
|
||||||
|
}</fold>
|
||||||
|
// </editor-fold></fold>
|
||||||
|
|
||||||
|
fun xyzzy() <fold text='{...}' expand='true'>{
|
||||||
|
<fold text='Body' expand='true'>// <editor-fold desc="Body">
|
||||||
|
printn("Xyzzy")
|
||||||
|
printn("Xyzzy")
|
||||||
|
printn("Xyzzy")
|
||||||
|
// </editor-fold></fold>
|
||||||
|
}</fold>
|
||||||
|
}</fold>
|
||||||
|
|
||||||
@@ -88,6 +88,12 @@ public class KotlinFoldingTestGenerated extends AbstractKotlinFoldingTest {
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/folding/checkCollapse"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/folding/checkCollapse"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("customRegions.kt")
|
||||||
|
public void testCustomRegions() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/folding/checkCollapse/customRegions.kt");
|
||||||
|
doSettingsFoldingTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("functionLiteral.kt")
|
@TestMetadata("functionLiteral.kt")
|
||||||
public void testFunctionLiteral() throws Exception {
|
public void testFunctionLiteral() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/folding/checkCollapse/functionLiteral.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/folding/checkCollapse/functionLiteral.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user