use of com.intellij.lang.folding.FoldingDescriptor in project intellij-community by JetBrains.
the class DocumentFoldingInfo method setToEditor.
@Override
public void setToEditor(@NotNull final Editor editor) {
assertDispatchThread();
final PsiManager psiManager = PsiManager.getInstance(myProject);
if (psiManager.isDisposed())
return;
if (!myFile.isValid())
return;
final PsiFile psiFile = psiManager.findFile(myFile);
if (psiFile == null)
return;
if (!mySerializedElements.isEmpty()) {
// Restore postponed state
assert myPsiElements.isEmpty() : "Sequential deserialization";
for (SerializedPsiElement entry : mySerializedElements) {
PsiElement restoredElement = FoldingPolicy.restoreBySignature(psiFile, entry.mySerializedElement);
if (restoredElement != null && restoredElement.isValid()) {
myPsiElements.add(SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(restoredElement));
restoredElement.putUserData(FOLDING_INFO_KEY, entry.myFoldingInfo);
}
}
mySerializedElements.clear();
}
Map<PsiElement, FoldingDescriptor> ranges = null;
for (SmartPsiElementPointer<PsiElement> ptr : myPsiElements) {
PsiElement element = ptr.getElement();
if (element == null || !element.isValid()) {
continue;
}
if (ranges == null) {
ranges = buildRanges(editor, psiFile);
}
FoldingDescriptor descriptor = ranges.get(element);
if (descriptor == null) {
continue;
}
TextRange range = descriptor.getRange();
FoldRegion region = FoldingUtil.findFoldRegion(editor, range.getStartOffset(), range.getEndOffset());
if (region != null) {
FoldingInfo fi = element.getUserData(FOLDING_INFO_KEY);
boolean state = fi != null && fi.expanded;
region.setExpanded(state);
}
}
for (RangeMarker marker : myRangeMarkers) {
if (!marker.isValid() || marker.getStartOffset() == marker.getEndOffset()) {
continue;
}
FoldRegion region = FoldingUtil.findFoldRegion(editor, marker.getStartOffset(), marker.getEndOffset());
FoldingInfo info = marker.getUserData(FOLDING_INFO_KEY);
if (region == null) {
if (info != null) {
region = editor.getFoldingModel().addFoldRegion(marker.getStartOffset(), marker.getEndOffset(), info.placeHolder);
}
if (region == null) {
return;
}
}
boolean state = info != null && info.expanded;
region.setExpanded(state);
}
}
use of com.intellij.lang.folding.FoldingDescriptor in project intellij-community by JetBrains.
the class CustomFileTypeFoldingBuilder method buildBraceMatcherBasedFolding.
public static void buildBraceMatcherBasedFolding(List<FoldingDescriptor> descriptors, PsiElement root, Document document, SyntaxHighlighter highlighter) {
LexerEditorHighlighter editorHighlighter = new LexerEditorHighlighter(highlighter, EditorColorsManager.getInstance().getGlobalScheme());
editorHighlighter.setText(document.getText());
FileType fileType = root.getContainingFile().getFileType();
BraceMatcher braceMatcher = BraceMatchingUtil.getBraceMatcher(fileType, root.getLanguage());
TextRange totalRange = root.getTextRange();
final HighlighterIterator iterator = editorHighlighter.createIterator(totalRange.getStartOffset());
final LinkedList<Trinity<Integer, Integer, IElementType>> stack = new LinkedList<>();
String editorText = document.getText();
while (!iterator.atEnd() && iterator.getStart() < totalRange.getEndOffset()) {
final Trinity<Integer, Integer, IElementType> last;
if (braceMatcher.isLBraceToken(iterator, editorText, fileType) && braceMatcher.isStructuralBrace(iterator, editorText, fileType)) {
stack.addLast(Trinity.create(iterator.getStart(), iterator.getEnd(), iterator.getTokenType()));
} else if (braceMatcher.isRBraceToken(iterator, editorText, fileType) && braceMatcher.isStructuralBrace(iterator, editorText, fileType) && !stack.isEmpty() && braceMatcher.isPairBraces((last = stack.getLast()).third, iterator.getTokenType())) {
stack.removeLast();
TextRange range = new TextRange(last.first, iterator.getEnd());
if (StringUtil.countChars(document.getText(range), '\n') >= 3) {
descriptors.add(new FoldingDescriptor(root, range));
}
}
iterator.advance();
}
}
use of com.intellij.lang.folding.FoldingDescriptor in project intellij-community by JetBrains.
the class IndentationFoldingBuilder method collectDescriptors.
private void collectDescriptors(@NotNull final ASTNode node, @NotNull final List<FoldingDescriptor> descriptors) {
final Queue<ASTNode> toProcess = new LinkedList<>();
toProcess.add(node);
while (!toProcess.isEmpty()) {
final ASTNode current = toProcess.remove();
if (current.getTreeParent() != null && current.getTextLength() > 1 && myTokenSet.contains(current.getElementType())) {
descriptors.add(new FoldingDescriptor(current, current.getTextRange()));
}
for (ASTNode child = current.getFirstChildNode(); child != null; child = child.getTreeNext()) {
toProcess.add(child);
}
}
}
use of com.intellij.lang.folding.FoldingDescriptor in project intellij-community by JetBrains.
the class JavaFoldingBuilderBase method addCommentFolds.
/**
* We want to allow to fold subsequent single line comments like
* <pre>
* // this is comment line 1
* // this is comment line 2
* </pre>
*
* @param comment comment to check
* @param processedComments set that contains already processed elements. It is necessary because we process all elements of
* the PSI tree, hence, this method may be called for both comments from the example above. However,
* we want to create fold region during the first comment processing, put second comment to it and
* skip processing when current method is called for the second element
* @param foldElements fold descriptors holder to store newly created descriptor (if any)
*/
private static void addCommentFolds(@NotNull PsiComment comment, @NotNull Set<PsiElement> processedComments, @NotNull List<FoldingDescriptor> foldElements) {
if (processedComments.contains(comment) || comment.getTokenType() != JavaTokenType.END_OF_LINE_COMMENT) {
return;
}
PsiElement end = null;
boolean containsCustomRegionMarker = isCustomRegionElement(comment);
for (PsiElement current = comment.getNextSibling(); current != null; current = current.getNextSibling()) {
ASTNode node = current.getNode();
if (node == null) {
break;
}
IElementType elementType = node.getElementType();
if (elementType == JavaTokenType.END_OF_LINE_COMMENT) {
end = current;
// We don't want to process, say, the second comment in case of three subsequent comments when it's being examined
// during all elements traversal. I.e. we expect to start from the first comment and grab as many subsequent
// comments as possible during the single iteration.
processedComments.add(current);
containsCustomRegionMarker |= isCustomRegionElement(current);
continue;
}
if (elementType == TokenType.WHITE_SPACE) {
continue;
}
break;
}
if (end != null && !containsCustomRegionMarker) {
foldElements.add(new FoldingDescriptor(comment, new TextRange(comment.getTextRange().getStartOffset(), end.getTextRange().getEndOffset())));
}
}
use of com.intellij.lang.folding.FoldingDescriptor in project intellij-community by JetBrains.
the class GroovyFoldingBuilder method addFoldingForStrings.
private static void addFoldingForStrings(List<FoldingDescriptor> descriptors, ASTNode node) {
if (!isMultiLineStringLiteral(node))
return;
if (!node.getElementType().equals(GroovyElementTypes.GSTRING) && !node.getElementType().equals(GroovyElementTypes.REGEX)) {
descriptors.add(new FoldingDescriptor(node, node.getTextRange()));
return;
}
final GrString grString = (GrString) node.getPsi();
if (grString == null)
return;
final GrStringInjection[] injections = grString.getInjections();
if (injections.length == 0) {
descriptors.add(new FoldingDescriptor(node, node.getTextRange()));
return;
}
final String start_quote = GrStringUtil.getStartQuote(node.getText());
final String end_quote = GrStringUtil.getEndQuote(node.getText());
final FoldingGroup group = FoldingGroup.newGroup("GString");
final TextRange nodeRange = node.getTextRange();
int startOffset = nodeRange.getStartOffset();
GrStringInjection injection = injections[0];
TextRange injectionRange = injection.getTextRange();
if (startOffset + 1 < injectionRange.getStartOffset()) {
descriptors.add(new NamedFoldingDescriptor(node, startOffset, injectionRange.getStartOffset(), group, start_quote));
}
final String placeholder = " ";
startOffset = injectionRange.getEndOffset();
for (int i = 1; i < injections.length; i++) {
injection = injections[i];
injectionRange = injection.getTextRange();
final int endOffset = injectionRange.getStartOffset();
if (endOffset - startOffset >= 2) {
descriptors.add(new NamedFoldingDescriptor(injection.getNode().getTreePrev(), startOffset, endOffset, group, placeholder));
}
startOffset = injectionRange.getEndOffset();
}
if (startOffset + 1 < nodeRange.getEndOffset()) {
descriptors.add(new NamedFoldingDescriptor(node.getLastChildNode(), startOffset, nodeRange.getEndOffset(), group, end_quote));
}
}
Aggregations