Skip to content

Commit 62c6e85

Browse files
committed
fix: improve folding speed
1 parent 4d4e9af commit 62c6e85

3 files changed

Lines changed: 31 additions & 23 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.gradle
2+
.kotlin
23
build/
34
!gradle/wrapper/gradle-wrapper.jar
45
!**/src/main/**/build/

src/main/kotlin/dev/zbinski/htmlattributefolder/AttributeFolder.kt

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package dev.zbinski.htmlattributefolder
22

33
import com.intellij.psi.PsiElement
4-
import kotlinx.coroutines.runBlocking
54

65
import com.intellij.openapi.util.TextRange
76
import com.intellij.openapi.editor.Document
@@ -12,12 +11,20 @@ import com.intellij.lang.ASTNode
1211
import com.intellij.lang.folding.FoldingBuilderEx
1312
import com.intellij.lang.folding.FoldingDescriptor
1413

14+
private data class AttributePrefix(val name: String, val doubleQuote: String, val singleQuote: String, val brace: String)
15+
1516
class AttributeFolder: FoldingBuilderEx(), DumbAware {
1617
private val settings = AttributeFolderState.instance
1718

18-
override fun buildFoldRegions(root: PsiElement, document: Document, quick: Boolean): Array<FoldingDescriptor> = runBlocking {
19+
override fun buildFoldRegions(root: PsiElement, document: Document, quick: Boolean): Array<FoldingDescriptor> {
20+
val attributes = settings.attributes
21+
val prefixes = attributes.map { name ->
22+
AttributePrefix(name, "$name=\"", "$name='", "$name={")
23+
}
24+
val minPrefixLen = prefixes.minOfOrNull { minOf(it.doubleQuote.length, it.singleQuote.length, it.brace.length) } ?: return emptyArray()
25+
1926
val descriptors = ArrayList<FoldingDescriptor>()
20-
for (item in getAttributes(Array(1) { root })) {
27+
for (item in getAttributes(Array(1) { root }, prefixes, minPrefixLen)) {
2128
var end: Int
2229
var start: Int
2330

@@ -80,7 +87,7 @@ class AttributeFolder: FoldingBuilderEx(), DumbAware {
8087
}
8188
}
8289

83-
return@runBlocking descriptors.toTypedArray()
90+
return descriptors.toTypedArray()
8491
}
8592

8693
override fun getPlaceholderText(node: ASTNode): String {
@@ -116,28 +123,28 @@ class AttributeFolder: FoldingBuilderEx(), DumbAware {
116123

117124
private fun getAttributes(
118125
elements: Array<PsiElement>,
119-
attributes: ArrayList<String> = settings.attributes
126+
prefixes: List<AttributePrefix>,
127+
minPrefixLen: Int
120128
): Sequence<Attribute> = sequence {
121129
for (child in elements) {
122-
val t = child.text
123-
for (attributeName in attributes) {
124-
val startsLikeAttribute =
125-
t.startsWith("$attributeName=\"") ||
126-
t.startsWith("$attributeName='") ||
127-
t.startsWith("$attributeName={")
128-
129-
if (startsLikeAttribute) {
130-
yield(object : Attribute {
131-
override val attribute = child
132-
override val attributeName = attributeName
133-
})
130+
if (child.textLength >= minPrefixLen) {
131+
val t = child.text
132+
for (prefix in prefixes) {
133+
val startsLikeAttribute =
134+
t.startsWith(prefix.doubleQuote) ||
135+
t.startsWith(prefix.singleQuote) ||
136+
t.startsWith(prefix.brace)
137+
138+
if (startsLikeAttribute) {
139+
yield(object : Attribute {
140+
override val attribute = child
141+
override val attributeName = prefix.name
142+
})
143+
}
134144
}
135145
}
136146

137-
val items = getAttributes(child.children, attributes).iterator()
138-
while (items.hasNext()) {
139-
yield(items.next())
140-
}
147+
yieldAll(getAttributes(child.children, prefixes, minPrefixLen))
141148
}
142149
}
143-
}
150+
}

src/main/kotlin/dev/zbinski/htmlattributefolder/AttributeFolderAction.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class AttributeFolderAction : AnAction() {
1010
private val settings = AttributeFolderState.instance
1111

1212
private fun getFoldRegionsForRelevantAttributes(foldRegions: Array<FoldRegion>): List<FoldRegion> {
13-
val relevantAttributes = settings.attributes
13+
val relevantAttributes = settings.attributes.toHashSet()
1414

1515
// Identifying a fold based on its "groupName"/"debugName" is possible because all folds relevant
1616
// to us have a self-defined `FoldingGroup` including the "groupname"/"debugName".

0 commit comments

Comments
 (0)