@NotNull @Override public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) { List<FoldingDescriptor> descriptors = new ArrayList<>(); PsiTreeUtil.processElements(root, element -> { IElementType elementType = element.getNode().getElementType(); MlTypes types = elementType.getLanguage() == RmlLanguage.INSTANCE ? RmlTypes.INSTANCE : OclTypes.INSTANCE; if (types.COMMENT == elementType) { FoldingDescriptor fold = fold(element); if (fold != null) { descriptors.add(fold); } } else if (types.TYPE_EXPRESSION == elementType) { foldType(descriptors, (PsiType) element); } else if (types.LET_EXPRESSION == elementType) { foldLet(descriptors, (PsiLet) element); } else if (types.MODULE_EXPRESSION == elementType) { foldModule(descriptors, (PsiModule) element); } return true; }); return descriptors.toArray(new FoldingDescriptor[descriptors.size()]); }
@NotNull @Override public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) { FoldingGroup group = FoldingGroup.newGroup("TYPO3Route"); List<FoldingDescriptor> descriptors = new ArrayList<>(); Collection<StringLiteralExpression> literalExpressions = PsiTreeUtil.findChildrenOfType(root, StringLiteralExpression.class); for (final StringLiteralExpression literalExpression : literalExpressions) { for (PsiReference reference : literalExpression.getReferences()) { if (reference instanceof RouteReference) { String value = literalExpression.getContents(); FoldingDescriptor descriptor = foldRouteReferenceString(reference, value, group); if (descriptor != null) { descriptors.add(descriptor); } } } } return descriptors.toArray(new FoldingDescriptor[descriptors.size()]); }
@NotNull @Override public FoldingDescriptor[] buildFoldRegions( @NotNull final PsiElement root, @NotNull final Document document, final boolean quick ) { if (!(root instanceof BladeFileImpl)) { return FoldingDescriptor.EMPTY.clone(); } final Queue<BladePsiDirective> directives = new LinkedBlockingQueue(Arrays.asList(((BladeFileImpl) root).getDirectives())); final List<FoldingDescriptor> foldingDescriptors = new ArrayList<>(); processDirectives(null, directives, foldingDescriptors, document); return foldingDescriptors.toArray(new FoldingDescriptor[foldingDescriptors.size()]); }
private void appendDescriptors(final ASTNode node, final Document document, final List<FoldingDescriptor> descriptors) { if (node.getElementType() == GCMTypes.CLASS_DECLARATION || node.getElementType() == GCMTypes.CUSTOM_TYPE_DECLARATION) { TextRange fullRange = node.getTextRange(); if (fullRange.getEndOffset() - fullRange.getStartOffset() > 0) { try { int startOffset = fullRange.getStartOffset() + document.getText(fullRange).indexOf("{") + 1; int endOffset = fullRange.getEndOffset() - 1; if (startOffset < endOffset) { TextRange shortRange = new TextRange(startOffset, fullRange.getEndOffset() - 1); if (shortRange.getEndOffset() - shortRange.getStartOffset() > 1) { descriptors.add(new FoldingDescriptor(node, shortRange)); } } } catch (Throwable e) { } } } ASTNode child = node.getFirstChildNode(); while (child != null) { appendDescriptors(child, document, descriptors); child = child.getTreeNext(); } }
@NotNull @Override public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement psiElement, @NotNull Document document, boolean quick) { if (!psiElement.getClass().getCanonicalName() .equals("org.jetbrains.kotlin.psi.KtFile") || quick || !LoggerFoldingApplicationSettings.getInstance() .getState() .getCollapseByDefault()) { return new FoldingDescriptor[0]; } List<FoldingDescriptor> foldingDescriptors = new LinkedList<>(); Project project = psiElement.getProject(); LoggerFoldingProjectSettings.State state = LoggerFoldingProjectSettings.getInstance(project).getState(); buildFoldRegions(psiElement, foldingDescriptors, state); return foldingDescriptors.toArray(new FoldingDescriptor[foldingDescriptors.size()]); }
@NotNull @Override public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement psiElement, @NotNull Document document, boolean quick) { if (!(psiElement instanceof PsiJavaFile) || quick || !LoggerFoldingApplicationSettings.getInstance().getState() .getCollapseByDefault()) { return new FoldingDescriptor[0]; } List<FoldingDescriptor> foldingDescriptors = new LinkedList<>(); Project project = psiElement.getProject(); LoggerFoldingProjectSettings.State state = LoggerFoldingProjectSettings.getInstance(project).getState(); buildFoldRegions(psiElement, foldingDescriptors, state); return foldingDescriptors.toArray(new FoldingDescriptor[foldingDescriptors.size()]); }
private static void collectDescriptorsRecursively(@NotNull ASTNode node, @NotNull Document document, @NotNull List<FoldingDescriptor> descriptors) { final IElementType type = node.getElementType(); if (type == token(COMMENT) && spanMultipleLines(node, document)) { descriptors.add(new FoldingDescriptor(node, node.getTextRange())); } if (type == token(LINE_COMMENT)) { final Couple<PsiElement> commentRange = expandLineCommentsRange(node.getPsi()); final int startOffset = commentRange.getFirst().getTextRange().getStartOffset(); final int endOffset = commentRange.getSecond().getTextRange().getEndOffset(); if (document.getLineNumber(startOffset) != document.getLineNumber(endOffset)) { descriptors.add(new FoldingDescriptor(node, new TextRange(startOffset, endOffset))); } } if (PROVIDERS.keySet().contains(type) && spanMultipleLines(node, document)) { descriptors.add(new FoldingDescriptor(node, node.getTextRange())); } for (ASTNode child : node.getChildren(null)) { collectDescriptorsRecursively(child, document, descriptors); } }
@SuppressWarnings("unchecked") @NotNull @Override public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) { Collection<? extends PsiElement> objects = PsiTreeUtil.findChildrenOfAnyType(root, IonObject.class, IonArray.class, IonExpression.class); if (objects.isEmpty()) { return new FoldingDescriptor[0]; } List<FoldingDescriptor> descriptors = new ArrayList<FoldingDescriptor>(); for (PsiElement object : objects) { final int startOffset = object.getTextRange().getStartOffset() + 1; final int endOffset = object.getTextRange().getEndOffset() - 1; if ((startOffset + 1) < endOffset) { TextRange range = new TextRange(startOffset, endOffset); descriptors.add(new FoldingDescriptor(object.getNode(), range)); } } return descriptors.toArray(new FoldingDescriptor[descriptors.size()]); }
private void addAnnotationsToFold(PsiModifierList modifierList, List<FoldingDescriptor> foldElements, Document document) { if (modifierList == null) return; PsiElement[] children = modifierList.getChildren(); for (int i = 0; i < children.length; i++) { PsiElement child = children[i]; if (child instanceof PsiAnnotation) { addToFold(foldElements, child, document, false); int j; for (j = i + 1; j < children.length; j++) { PsiElement nextChild = children[j]; if (nextChild instanceof PsiModifier) break; } //noinspection AssignmentToForLoopParameter i = j; } } }
private static void addMethodGenericParametersFolding(PsiMethodCallExpression expression, List<FoldingDescriptor> foldElements, Document document, boolean quick) { final PsiReferenceExpression methodExpression = expression.getMethodExpression(); final PsiReferenceParameterList list = methodExpression.getParameterList(); if (list == null || list.getTextLength() <= 5) { return; } PsiMethodCallExpression element = expression; while (true) { if (!quick && !resolvesCorrectly(element.getMethodExpression())) return; final PsiElement parent = element.getParent(); if (!(parent instanceof PsiExpressionList) || !(parent.getParent() instanceof PsiMethodCallExpression)) break; element = (PsiMethodCallExpression)parent.getParent(); } addTypeParametersFolding(foldElements, document, list, 3, quick); }
private static void addTypeParametersFolding(List<FoldingDescriptor> foldElements, Document document, PsiReferenceParameterList list, final int ifLongerThan, boolean quick) { if (!quick) { for (final PsiType type : list.getTypeArguments()) { if (!type.isValid()) { return; } if (type instanceof PsiClassType || type instanceof PsiArrayType) { if (PsiUtil.resolveClassInType(type) == null) { return; } } } } final String text = list.getText(); if (text.startsWith("<") && text.endsWith(">") && text.length() > ifLongerThan) { final TextRange range = list.getTextRange(); addFoldRegion(foldElements, list, document, true, range); } }
@NotNull public List<FoldingDescriptor> buildDescriptors() { myCallArguments = getArguments(myCallExpression); if (myCallArguments != null && myCallArguments.length >= MIN_ARGS_TO_FOLD && hasLiteralExpression(myCallArguments)) { PsiMethod method = myCallExpression.resolveMethod(); if (method != null) { myParameters = method.getParameterList().getParameters(); if (myParameters.length == myCallArguments.length) { return buildDescriptorsForLiteralArguments(); } } } return ContainerUtil.emptyList(); }
@NotNull private List<FoldingDescriptor> buildDescriptorsForLiteralArguments() { List<FoldingDescriptor> descriptors = ContainerUtil.newArrayList(); int i = 0; while (i < myCallArguments.length) { if (i + 1 < myCallArguments.length && isCommonlyNamedParameterPair(i, i + 1)) { i += 2; continue; } if (shouldInlineParameterName(i)) { descriptors.add(createFoldingDescriptor(myCallArguments[i], myParameters[i])); } i++; } return descriptors; }
@NotNull @Override public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) { if (!(root instanceof PsiJavaFile) || quick || !JavaCodeFoldingSettings.getInstance().isCollapseSuppressWarnings()) { return FoldingDescriptor.EMPTY; } if (!PsiUtil.isLanguageLevel5OrHigher(root)) { return FoldingDescriptor.EMPTY; } final List<FoldingDescriptor> result = new ArrayList<FoldingDescriptor>(); root.accept(new JavaRecursiveElementWalkingVisitor(){ @Override public void visitAnnotation(PsiAnnotation annotation) { if (Comparing.strEqual(annotation.getQualifiedName(), SuppressWarnings.class.getName())) { result.add(new FoldingDescriptor(annotation, annotation.getTextRange())); } super.visitAnnotation(annotation); } }); return result.toArray(new FoldingDescriptor[result.size()]); }
private void collectDescriptors(@NotNull final ASTNode node, @NotNull final List<FoldingDescriptor> descriptors) { final Queue<ASTNode> toProcess = new LinkedList<ASTNode>(); 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); } } }
@NotNull private static Map<PsiElement, FoldingDescriptor> buildRanges(@NotNull Editor editor, @NotNull PsiFile psiFile) { final FoldingBuilder foldingBuilder = LanguageFolding.INSTANCE.forLanguage(psiFile.getLanguage()); final ASTNode node = psiFile.getNode(); if (node == null) return Collections.emptyMap(); final FoldingDescriptor[] descriptors = LanguageFolding.buildFoldingDescriptors(foldingBuilder, psiFile, editor.getDocument(), true); Map<PsiElement, FoldingDescriptor> ranges = new HashMap<PsiElement, FoldingDescriptor>(); for (FoldingDescriptor descriptor : descriptors) { final ASTNode ast = descriptor.getElement(); final PsiElement psi = ast.getPsi(); if (psi != null) { ranges.put(psi, descriptor); } } return ranges; }
private static CachedValueProvider.Result<Runnable> getUpdateResult(PsiFile file, @NotNull Document document, boolean quick, final Project project, final Editor editor, final boolean applyDefaultState) { final FoldingMap elementsToFoldMap = getFoldingsFor(file, document, quick); final UpdateFoldRegionsOperation operation = new UpdateFoldRegionsOperation(project, editor, file, elementsToFoldMap, applyDefaultState ? EXCEPT_CARET_REGION : NO, false); Runnable runnable = new Runnable() { @Override public void run() { editor.getFoldingModel().runBatchFoldingOperationDoNotCollapseCaret(operation); } }; Set<Object> dependencies = new HashSet<Object>(); dependencies.add(document); for (FoldingDescriptor descriptor : elementsToFoldMap.values()) { dependencies.addAll(descriptor.getDependencies()); } return CachedValueProvider.Result.create(runnable, ArrayUtil.toObjectArray(dependencies)); }
CustomFoldingRegionsPopup(@NotNull Collection<FoldingDescriptor> descriptors, @NotNull final Editor editor, @NotNull final Project project) { myEditor = editor; myRegionsList = new JBList(); //noinspection unchecked myRegionsList.setModel(new MyListModel(orderByPosition(descriptors))); myRegionsList.setSelectedIndex(0); final PopupChooserBuilder popupBuilder = JBPopupFactory.getInstance().createListPopupBuilder(myRegionsList); myPopup = popupBuilder .setTitle(IdeBundle.message("goto.custom.region.command")) .setResizable(false) .setMovable(false) .setItemChoosenCallback(new Runnable() { @Override public void run() { PsiElement navigationElement = getNavigationElement(); if (navigationElement != null) { navigateTo(editor, navigationElement); IdeDocumentHistory.getInstance(project).includeCurrentCommandAsNavigation(); } } }).createPopup(); }
private static void collectDescriptorsRecursively(@NotNull ASTNode node, @NotNull Document document, @NotNull List<FoldingDescriptor> descriptors) { final IElementType type = node.getElementType(); if ((type == JsonElementTypes.OBJECT || type == JsonElementTypes.ARRAY) && spanMultipleLines(node, document)) { descriptors.add(new FoldingDescriptor(node, node.getTextRange())); } else if (type == JsonElementTypes.BLOCK_COMMENT) { descriptors.add(new FoldingDescriptor(node, node.getTextRange())); } else if (type == JsonElementTypes.LINE_COMMENT) { final Couple<PsiElement> commentRange = expandLineCommentsRange(node.getPsi()); final int startOffset = commentRange.getFirst().getTextRange().getStartOffset(); final int endOffset = commentRange.getSecond().getTextRange().getEndOffset(); if (document.getLineNumber(startOffset) != document.getLineNumber(endOffset)) { descriptors.add(new FoldingDescriptor(node, new TextRange(startOffset, endOffset))); } } for (ASTNode child : node.getChildren(null)) { collectDescriptorsRecursively(child, document, descriptors); } }
private static void appendDescriptors(ASTNode node, List<FoldingDescriptor> descriptors) { if (node.getElementType() instanceof PyFileElementType) { final List<PyImportStatementBase> imports = ((PyFile)node.getPsi()).getImportBlock(); if (imports.size() > 1) { final PyImportStatementBase firstImport = imports.get(0); final PyImportStatementBase lastImport = imports.get(imports.size()-1); descriptors.add(new FoldingDescriptor(firstImport, new TextRange(firstImport.getTextRange().getStartOffset(), lastImport.getTextRange().getEndOffset()))); } } else if (node.getElementType() == PyElementTypes.STATEMENT_LIST) { foldStatementList(node, descriptors); } else if (node.getElementType() == PyElementTypes.STRING_LITERAL_EXPRESSION) { foldDocString(node, descriptors); } ASTNode child = node.getFirstChildNode(); while (child != null) { appendDescriptors(child, descriptors); child = child.getTreeNext(); } }
private static void foldStatementList(ASTNode node, List<FoldingDescriptor> descriptors) { IElementType elType = node.getTreeParent().getElementType(); if (elType == PyElementTypes.FUNCTION_DECLARATION || elType == PyElementTypes.CLASS_DECLARATION) { ASTNode colon = node.getTreeParent().findChildByType(PyTokenTypes.COLON); if (colon != null && colon.getStartOffset() + 1 < node.getTextRange().getEndOffset() - 1) { final CharSequence chars = node.getChars(); int nodeStart = node.getTextRange().getStartOffset(); int endOffset = node.getTextRange().getEndOffset(); while(endOffset > colon.getStartOffset()+2 && endOffset > nodeStart && Character.isWhitespace(chars.charAt(endOffset - nodeStart - 1))) { endOffset--; } descriptors.add(new FoldingDescriptor(node, new TextRange(colon.getStartOffset() + 1, endOffset))); } else { TextRange range = node.getTextRange(); if (range.getStartOffset() < range.getEndOffset() - 1) { // only for ranges at least 1 char wide descriptors.add(new FoldingDescriptor(node, range)); } } } }
protected boolean addToFold(List<FoldingDescriptor> foldings, PsiElement elementToFold, Document document) { PsiUtilCore.ensureValid(elementToFold); TextRange range = getRangeToFold(elementToFold); if (range == null) return false; if(range.getStartOffset() >= 0 && range.getEndOffset() <= elementToFold.getContainingFile().getTextRange().getEndOffset() && range.getEndOffset() <= document.getTextLength() // psi and document maybe not in sync after error ) { int startLine = document.getLineNumber(range.getStartOffset()); int endLine = document.getLineNumber(range.getEndOffset() - 1); if (startLine < endLine || elementToFold instanceof XmlAttribute) { if (range.getStartOffset() + MIN_TEXT_RANGE_LENGTH < range.getEndOffset()) { foldings.add(new FoldingDescriptor(elementToFold.getNode(), range)); return true; } } } return false; }
@Nullable private static ASTNode checkNodeAndSiblings(@Nullable ASTNode node, TokenSet tokens, ArrayList<FoldingDescriptor> regions, Document document) { if (node != null && tokens.contains(node.getElementType())) { final ASTNode start = node; ASTNode end = start; node = node.getTreeNext(); if (node != null) { do { end = node; node = node.getTreeNext(); } while (node != null && tokens.contains(node.getElementType())); } if (end != start) { while (end.getPsi() instanceof PsiWhiteSpace) { end = end.getTreePrev(); } if (isOnDifferentLine(start, end, document)) { regions.add(new FoldingDescriptor(start, new TextRange(start.getStartOffset(), end.getTextRange().getEndOffset()))); } } } return node; }
private static InlinedResource createdInlinedResource(@NotNull ResourceType type, @NotNull String name, @NotNull PsiElement foldElement) { // Not part of a call: just fold the R.string reference itself LocalResourceRepository appResources = getAppResources(foldElement); if (appResources != null && appResources.hasResourceItem(type, name)) { ASTNode node = foldElement.getNode(); if (node != null) { TextRange textRange = foldElement.getTextRange(); HashSet<Object> dependencies = new HashSet<Object>(); dependencies.add(foldElement); FoldingDescriptor descriptor = new FoldingDescriptor(node, textRange, null, dependencies); InlinedResource inlinedResource = new InlinedResource(type, name, appResources, descriptor, foldElement); dependencies.add(inlinedResource); return inlinedResource; } } return NONE; }
private static void collapseBlock(List<FoldingDescriptor> descriptors, PsiElement psi) { if (psi instanceof GrCodeBlock) { final int lineFeedCount = StringUtil.countChars(psi.getText(), '\n'); if (lineFeedCount <= 2) { final PsiElement lbrace = ((GrCodeBlock)psi).getLBrace(); final PsiElement rbrace = ((GrCodeBlock)psi).getRBrace(); if (lbrace != null && rbrace != null) { final PsiElement next = lbrace.getNextSibling(); final PsiElement prev = rbrace.getPrevSibling(); if (next != null && PsiImplUtil.isWhiteSpaceOrNls(next) && prev != null && PsiImplUtil.isWhiteSpaceOrNls(prev)) { final FoldingGroup group = FoldingGroup.newGroup("block_group"); descriptors.add(new NamedFoldingDescriptor(psi, lbrace.getTextRange().getStartOffset(), next.getTextRange().getEndOffset(), group, "{")); descriptors.add(new NamedFoldingDescriptor(psi, prev.getTextRange().getStartOffset(), rbrace.getTextRange().getEndOffset(), group, "}")); return; } } } } descriptors.add(new FoldingDescriptor(psi, psi.getTextRange())); }
private static void processImports(final List<FoldingDescriptor> descriptors, GrImportStatement[] imports) { if (imports.length < 2) return; PsiElement first = imports[0]; while (first != null) { PsiElement marker = first; PsiElement next = first.getNextSibling(); while (next instanceof GrImportStatement || next instanceof LeafPsiElement) { if (next instanceof GrImportStatement) marker = next; next = next.getNextSibling(); } if (marker != first) { int start = first.getTextRange().getStartOffset(); int end = marker.getTextRange().getEndOffset(); int tail = "import ".length(); if (start + tail < end && !JavaFoldingBuilderBase.hasErrorElementsNearby(first.getContainingFile(), start, end)) { descriptors.add(new FoldingDescriptor(first.getNode(), new TextRange(start + tail, end))); } } while (!(next instanceof GrImportStatement) && next != null) next = next.getNextSibling(); first = next; } }
@Test public void testFuncDefStatementsFolded() { BuildFile file = createBuildFile( new WorkspacePath("java/com/google/BUILD"), "# multi-line comment, not folded", "# second line of comment", "def function(arg1, arg2):", " stmt1", " stmt2", "", "variable = 1"); FoldingDescriptor[] foldingRegions = getFoldingRegions(file); assertThat(foldingRegions).hasLength(1); assertThat(foldingRegions[0].getElement().getPsi()) .isEqualTo(file.findFunctionInScope("function")); }
@Test public void testLoadStatementFolded() { BuildFile file = createBuildFile( new WorkspacePath("java/com/google/BUILD"), "load(", " '//java/com/foo/build_defs.bzl',", " 'function1',", " 'function2',", ")"); FoldingDescriptor[] foldingRegions = getFoldingRegions(file); assertThat(foldingRegions).hasLength(1); assertThat(foldingRegions[0].getElement().getPsi()) .isEqualTo(file.findChildByClass(LoadStatement.class)); }
@NotNull @Override public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement psiElement, @NotNull Document document, boolean b) { if (!(psiElement instanceof PhpFile)) { return new FoldingDescriptor[0]; } List<FoldingDescriptor> descriptors = new ArrayList<>(); Collection<PhpDocCommentImpl> phpDocs = PsiTreeUtil.findChildrenOfType(psiElement, PhpDocCommentImpl.class); for (Object phpDoc1 : phpDocs) { PhpDocCommentImpl phpDoc = (PhpDocCommentImpl) phpDoc1; this.attachBlockShortcuts(descriptors, phpDoc); } return descriptors.toArray(new FoldingDescriptor[descriptors.size()]); }
private void attachBlockShortcuts(List<FoldingDescriptor> descriptors, PhpDocCommentImpl phpDocComment) { final String comment = this.getPlaceholderTextForCommentImpl(phpDocComment); if (null == comment) { return; } int docPosition = phpDocComment.getTextRange().getStartOffset(); int positionInDocBlock = phpDocComment.getText().toLowerCase().indexOf("{@inheritdoc}"); int position = docPosition + positionInDocBlock; TextRange range = new TextRange(position, position + 13); descriptors.add(new FoldingDescriptor(phpDocComment.getNode(), range) { @NotNull public String getPlaceholderText() { return comment; } }); }
private void appendDescriptors(@NotNull final ASTNode node, @NotNull final List<FoldingDescriptor> descriptors) { final ASTNode firstChildNode = node.getFirstChildNode(); if (node.getText().isEmpty()) return; if (node.getElementType() == OCamlElementTypes.PARENTHESES_EXPRESSION && firstChildNode != null && firstChildNode.getElementType() == OCamlTokenTypes.BEGIN_KEYWORD || node.getElementType() == OCamlElementTypes.STRUCT_END_MODULE_EXPRESSION || node.getElementType() == OCamlElementTypes.SIG_END_MODULE_TYPE || node.getElementType() == OCamlElementTypes.OBJECT_CLASS_BODY_END_EXPRESSION || node.getElementType() == OCamlElementTypes.OBJECT_END_CLASS_BODY_TYPE || node.getElementType() == OCamlElementTypes.OBJECT_END_CLASS_EXPRESSION || node.getElementType() == OCamlElementTypes.COMMENT_BLOCK || node.getElementType() == OCamlElementTypes.UNCLOSED_COMMENT) { descriptors.add(new FoldingDescriptor(node, node.getTextRange())); } ASTNode child = firstChildNode; while (child != null) { appendDescriptors(child, descriptors); child = child.getTreeNext(); } }
@Override protected void buildLanguageFoldRegions(@NotNull final List<FoldingDescriptor> descriptors, @NotNull PsiElement root, @NotNull Document document, boolean quick) { root.accept(new SharpLabElementVisitor() { @Override public void visitElement(PsiElement element) { if(element instanceof ShaderBraceOwner) { descriptors.add(new FoldingDescriptor(element, element.getTextRange())); } element.acceptChildren(this); } }); }
@Override public void visitSection(@NotNull LatexSection section) { LatexInstructionBegin begin = ((LatexSectionExtImpl) section).getBeginInstruction(); LatexInstructionEnd end = ((LatexSectionExtImpl) section).getEndInstruction(); if (begin == null || end == null) { return; } int startOffset = begin.getTextOffset(); int endOffset = end.getTextOffset() + end.getTextLength(); if (endOffset - startOffset > 0) { descriptors.add(new FoldingDescriptor(section, new TextRange(startOffset, endOffset))); } section.acceptChildren(visitor); }
private void appendDescriptors(final ASTNode node, final List<FoldingDescriptor> descriptors) { IElementType type = node.getElementType(); final TextRange textRange = node.getTextRange(); //Don't add folding to 0-length nodes, crashes in new FoldingDescriptor if(textRange.getLength() <= 0)return; if (type == GLSLTokenTypes.COMMENT_BLOCK || type == GLSLElementTypes.COMPOUND_STATEMENT) { descriptors.add(new FoldingDescriptor(node, textRange)); } ASTNode child = node.getFirstChildNode(); while (child != null) { appendDescriptors(child, descriptors); child = child.getTreeNext(); } }
private static CachedValueProvider.Result<Runnable> getUpdateResult(PsiFile file, Document document, boolean quick, final Project project, final Editor editor, final boolean applyDefaultState) { final FoldingMap elementsToFoldMap = new FoldingMap(); if (!isContentSubstituted(file, project)) { getFoldingsFor(file instanceof PsiCompiledFile ? ((PsiCompiledFile)file).getDecompiledPsiFile() : file, document, elementsToFoldMap, quick); } final UpdateFoldRegionsOperation operation = new UpdateFoldRegionsOperation(project, editor, file, elementsToFoldMap, applyDefaultState, false); Runnable runnable = new Runnable() { @Override public void run() { editor.getFoldingModel().runBatchFoldingOperationDoNotCollapseCaret(operation); } }; Set<Object> dependencies = new HashSet<Object>(); dependencies.add(document); for (FoldingDescriptor descriptor : elementsToFoldMap.values()) { dependencies.addAll(descriptor.getDependencies()); } return CachedValueProvider.Result.create(runnable, ArrayUtil.toObjectArray(dependencies)); }