| /* |
| * Copyright 2000-2013 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.intellij.ide.highlighter.custom.impl; |
| |
| import com.intellij.codeInsight.highlighting.BraceMatcher; |
| import com.intellij.codeInsight.highlighting.BraceMatchingUtil; |
| import com.intellij.ide.highlighter.custom.CustomFileHighlighter; |
| import com.intellij.lang.ASTNode; |
| import com.intellij.lang.folding.CustomFoldingBuilder; |
| import com.intellij.lang.folding.FoldingDescriptor; |
| import com.intellij.openapi.editor.Document; |
| import com.intellij.openapi.editor.colors.EditorColorsManager; |
| import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter; |
| import com.intellij.openapi.editor.highlighter.HighlighterIterator; |
| import com.intellij.openapi.fileTypes.FileType; |
| import com.intellij.openapi.fileTypes.SyntaxHighlighter; |
| import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType; |
| import com.intellij.openapi.util.TextRange; |
| import com.intellij.openapi.util.Trinity; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.psi.PsiElement; |
| import com.intellij.psi.tree.IElementType; |
| import org.jetbrains.annotations.NotNull; |
| |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| /** |
| * @author yole |
| */ |
| public class CustomFileTypeFoldingBuilder extends CustomFoldingBuilder { |
| |
| @Override |
| protected void buildLanguageFoldRegions(@NotNull List<FoldingDescriptor> descriptors, |
| @NotNull PsiElement root, |
| @NotNull Document document, |
| boolean quick) { |
| FileType fileType = root.getContainingFile().getFileType(); |
| if (!(fileType instanceof CustomSyntaxTableFileType)) { |
| return; |
| } |
| CustomFileHighlighter highlighter = new CustomFileHighlighter(((CustomSyntaxTableFileType) fileType).getSyntaxTable()); |
| buildBraceMatcherBasedFolding(descriptors, root, document, highlighter); |
| } |
| |
| 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<Trinity<Integer, Integer, IElementType>>(); |
| 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(); |
| } |
| } |
| |
| @Override |
| protected String getLanguagePlaceholderText(@NotNull ASTNode node, @NotNull TextRange range) { |
| return "{...}"; |
| } |
| |
| @Override |
| protected boolean isRegionCollapsedByDefault(@NotNull ASTNode node) { |
| return false; |
| } |
| } |