-
-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fold Labeled Statements #195
Comments
Hi, LivePlugin is just compiling and loading classes into the JVM at runtime. It has a thin wrapper around some of the IDE APIs but fundamentally LivePlugin doesn't restrict you from doing anything (except that some IntelliJ APIs are not necessarily designed to be reloaded at runtime). Here is an example of If you want something a bit more basic, here is an older collapse java keywords into symbols action https://gist.github.com/dkandalov/5553999 |
This is awesome. Thank you. import com.intellij.lang.ASTNode
import com.intellij.lang.LanguageExtensionPoint
import com.intellij.lang.folding.CustomFoldingBuilder
import com.intellij.lang.folding.FoldingBuilder
import com.intellij.lang.folding.FoldingDescriptor
import com.intellij.lang.folding.LanguageFolding
import com.intellij.openapi.editor.Document
import com.intellij.openapi.extensions.DefaultPluginDescriptor
import com.intellij.openapi.extensions.PluginId
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.util.elementType
import com.intellij.util.KeyedLazyInstance
val pluginDescriptor =
DefaultPluginDescriptor(PluginId.getId("LivePlugin"), SpockFoldingBuilder::class.java.classLoader)
val extensionPoint: KeyedLazyInstance<FoldingBuilder> =
LanguageExtensionPoint("Groovy", "Plugin\$SpockFoldingBuilder", pluginDescriptor)
LanguageFolding.EP_NAME.point.registerExtension(extensionPoint, pluginDisposable)
class SpockFoldingBuilder : CustomFoldingBuilder(), DumbAware {
private val labels = setOf("and:", "expect:", "given:", "then:", "when:", "where:")
override fun buildLanguageFoldRegions(
descriptors: MutableList<FoldingDescriptor>,
root: PsiElement,
document: Document,
quick: Boolean,
) {
if (root.elementType?.language?.id != "Groovy") return
addSpockLabelFoldRegions(descriptors, root)
}
private fun addSpockLabelFoldRegions(descriptors: MutableList<FoldingDescriptor>, e: PsiElement) {
for (child in e.children) {
if (child.isSpockLabel())
addSpockLabelFoldRegion(descriptors, child)
addSpockLabelFoldRegions(descriptors, child)
}
}
private fun addSpockLabelFoldRegion(descriptors: MutableList<FoldingDescriptor>, e: PsiElement) {
var next = e.nextSibling
val start = e.textRange.startOffset
var end = e.textRange.endOffset
while (next != null && !(next.isSpockLabel())) {
if (!next.isWhiteSpaceOrNewLine())
end = next.textRange.endOffset
next = next.nextSibling
}
if (end > start) {
val range = TextRange(start, end)
descriptors.add(FoldingDescriptor(e.node, range))
}
}
@Suppress("UnstableApiUsage")
private fun PsiElement.isWhiteSpaceOrNewLine() =
this is PsiWhiteSpace || node.elementType.debugName == "new line"
@Suppress("UnstableApiUsage")
private fun PsiElement.isSpockLabel(): Boolean = this.elementType?.debugName == "LABELED_STATEMENT" &&
labels.stream().anyMatch { text.startsWith(it) }
override fun getLanguagePlaceholderText(node: ASTNode, range: TextRange) = node.text
override fun isRegionCollapsedByDefault(node: ASTNode) = false
} But unfortunately it doesn't seem to work. I'm not sure what the issue is, but the above works just fine in a proper plugin project. Thanks. |
I tried To debug you can show notifications or print to stdout (which ends up in the IDE log file). For example, see https://github.com/dkandalov/live-plugin/blob/master/plugin-examples/kotlin/hello-world/plugin.kts Not sure if breakpoints are possible because it will be JVM debugging itself. |
You’re right. Now it works. Not sure what happened. Thanks for the support. |
Hi there,
Objective: to be able to fold blocks in a Spock test (e.g.
given
,when
,then
, etc) for more readability and better code navigation in the IDEFor example, having something like this:


I'd like to be able to make it like this:
I wanted to implement this as a plugin, but it seemed to be an overkill and was hoping if LivePlugin can help with this.
I tried to find something in the repo and docs regarding folding, but couldn't find anything. Does LivePlugin support such functionalities, more specifically
FoldingBuilder
?I never developed plugins so might not be super helpful, but happy to contribute in any way I can.
Cheers.
The text was updated successfully, but these errors were encountered: