Skip to content

Commit 7099b09

Browse files
89: Support for custom folding regions
Fixes #89
1 parent c09a4e5 commit 7099b09

File tree

3 files changed

+57
-46
lines changed

3 files changed

+57
-46
lines changed

src/main/java/io/protostuff/jetbrains/plugin/ProtoFoldingBuilder.java

Lines changed: 40 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@
1414

1515
import com.google.common.collect.ImmutableMap;
1616
import com.intellij.lang.ASTNode;
17-
import com.intellij.lang.folding.FoldingBuilder;
17+
import com.intellij.lang.folding.CustomFoldingBuilder;
1818
import com.intellij.lang.folding.FoldingDescriptor;
1919
import com.intellij.openapi.editor.Document;
20-
import com.intellij.openapi.project.DumbAware;
2120
import com.intellij.openapi.util.Couple;
2221
import com.intellij.openapi.util.TextRange;
2322
import com.intellij.psi.PsiElement;
@@ -32,7 +31,6 @@
3231
import io.protostuff.jetbrains.plugin.psi.OneOfNode;
3332
import io.protostuff.jetbrains.plugin.psi.ServiceNode;
3433
import io.protostuff.jetbrains.plugin.psi.TypeReferenceNode;
35-
import java.util.ArrayList;
3634
import java.util.List;
3735
import java.util.Map;
3836
import java.util.function.Function;
@@ -44,7 +42,7 @@
4442
*
4543
* @author Kostiantyn Shchepanovskyi
4644
*/
47-
public class ProtoFoldingBuilder implements FoldingBuilder, DumbAware {
45+
public class ProtoFoldingBuilder extends CustomFoldingBuilder {
4846

4947
private static final Map<IElementType, Function<ASTNode, String>> PROVIDERS = ImmutableMap.<IElementType, Function<ASTNode, String>>builder()
5048
.put(rule(RULE_messageBlock), node -> {
@@ -82,48 +80,6 @@ public class ProtoFoldingBuilder implements FoldingBuilder, DumbAware {
8280
.put(token(COMMENT), node -> "/*...*/")
8381
.build();
8482

85-
@NotNull
86-
@Override
87-
public FoldingDescriptor[] buildFoldRegions(@NotNull ASTNode node, @NotNull Document document) {
88-
final List<FoldingDescriptor> descriptors = new ArrayList<>();
89-
collectDescriptorsRecursively(node, document, descriptors);
90-
return descriptors.toArray(new FoldingDescriptor[descriptors.size()]);
91-
}
92-
93-
@Nullable
94-
@Override
95-
public String getPlaceholderText(@NotNull ASTNode node) {
96-
final IElementType type = node.getElementType();
97-
Function<ASTNode, String> provider = PROVIDERS.getOrDefault(type, ast -> "...");
98-
return provider.apply(node);
99-
}
100-
101-
@Override
102-
public boolean isCollapsedByDefault(@NotNull ASTNode node) {
103-
// This code should collapse header comments.
104-
// However, in most of the cases it will not work,
105-
// as when file is open caret is at the beginning of the document,
106-
// thus preventing collapsing it.
107-
// TODO: Collapse header comment when file is opened
108-
return node.getTreeParent() instanceof FileElement
109-
&& findPreviousNonWhitespaceOrCommentNode(node) == null;
110-
}
111-
112-
@Nullable
113-
private ASTNode findPreviousNonWhitespaceOrCommentNode(@NotNull ASTNode node) {
114-
ASTNode tmp = node;
115-
while (tmp != null) {
116-
IElementType type = tmp.getElementType();
117-
if (!(tmp instanceof PsiWhiteSpace
118-
|| type == token(COMMENT)
119-
|| type == token(LINE_COMMENT))) {
120-
break;
121-
}
122-
tmp = tmp.getTreePrev();
123-
}
124-
return tmp;
125-
}
126-
12783
private static void collectDescriptorsRecursively(@NotNull ASTNode node,
12884
@NotNull Document document,
12985
@NotNull List<FoldingDescriptor> descriptors) {
@@ -179,4 +135,42 @@ private static boolean spanMultipleLines(@NotNull ASTNode node, @NotNull Documen
179135
final TextRange range = node.getTextRange();
180136
return document.getLineNumber(range.getStartOffset()) < document.getLineNumber(range.getEndOffset());
181137
}
138+
139+
@Override
140+
protected void buildLanguageFoldRegions(@NotNull List<FoldingDescriptor> descriptors, @NotNull PsiElement root, @NotNull Document document, boolean quick) {
141+
collectDescriptorsRecursively(root.getNode(), document, descriptors);
142+
}
143+
144+
@Override
145+
protected String getLanguagePlaceholderText(@NotNull ASTNode node, @NotNull TextRange range) {
146+
final IElementType type = node.getElementType();
147+
Function<ASTNode, String> provider = PROVIDERS.getOrDefault(type, ast -> "...");
148+
return provider.apply(node);
149+
}
150+
151+
@Override
152+
protected boolean isRegionCollapsedByDefault(@NotNull ASTNode node) {
153+
// This code should collapse header comments.
154+
// However, in most of the cases it will not work,
155+
// as when file is open caret is at the beginning of the document,
156+
// thus preventing collapsing it.
157+
// TODO: Collapse header comment when file is opened
158+
return node.getTreeParent() instanceof FileElement
159+
&& findPreviousNonWhitespaceOrCommentNode(node) == null;
160+
}
161+
162+
@Nullable
163+
private ASTNode findPreviousNonWhitespaceOrCommentNode(@NotNull ASTNode node) {
164+
ASTNode tmp = node;
165+
while (tmp != null) {
166+
IElementType type = tmp.getElementType();
167+
if (!(tmp instanceof PsiWhiteSpace
168+
|| type == token(COMMENT)
169+
|| type == token(LINE_COMMENT))) {
170+
break;
171+
}
172+
tmp = tmp.getTreePrev();
173+
}
174+
return tmp;
175+
}
182176
}

src/test/java/io/protostuff/jetbrains/plugin/folding/FoldingTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ public void testFoldExtension() {
4646
check();
4747
}
4848

49+
public void testFoldRegion() {
50+
check();
51+
}
52+
4953
private void check() {
5054
check(false);
5155
}
@@ -56,8 +60,10 @@ private void check(boolean checkCollapseStatus) {
5660
if (checkCollapseStatus) {
5761
myFixture.testFoldingWithCollapseStatus(getTestDataPath() + file);
5862
} else {
63+
5964
myFixture.testFolding(getTestDataPath() + file);
6065
}
6166
}
6267

68+
6369
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
syntax = "proto3";
2+
3+
package folding;
4+
5+
<fold text='message A {...}'>message A {
6+
<fold text='SomeRegionName'>// region SomeRegionName
7+
int32 x = 1;
8+
int32 y = 2;
9+
int32 z = 3;
10+
// endregion</fold>
11+
}</fold>

0 commit comments

Comments
 (0)