Search in sources :

Example 81 with TextRange

use of com.intellij.openapi.util.TextRange in project intellij-community by JetBrains.

the class XmlMover method checkAvailable.

//private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.actions.moveUpDown.XmlMover");
@Override
public boolean checkAvailable(@NotNull final Editor editor, @NotNull final PsiFile file, @NotNull final MoveInfo info, final boolean down) {
    if (!(file instanceof XmlFile)) {
        return false;
    }
    if (!super.checkAvailable(editor, file, info, down))
        return false;
    // updated moved range end to cover multiline tag start
    final Document document = editor.getDocument();
    int movedLineStart = document.getLineStartOffset(info.toMove.startLine);
    final int movedLineEnd = document.getLineEndOffset(info.toMove.endLine - 1);
    PsiElement movedEndElement = file.findElementAt(movedLineEnd);
    if (movedEndElement instanceof PsiWhiteSpace)
        movedEndElement = PsiTreeUtil.prevLeaf(movedEndElement);
    PsiElement movedStartElement = file.findElementAt(movedLineStart);
    if (movedStartElement instanceof PsiWhiteSpace)
        movedStartElement = PsiTreeUtil.nextLeaf(movedStartElement);
    if (movedEndElement == null || movedStartElement == null)
        return false;
    final PsiNamedElement namedParentAtEnd = PsiTreeUtil.getParentOfType(movedEndElement, PsiNamedElement.class);
    final PsiNamedElement namedParentAtStart = PsiTreeUtil.getParentOfType(movedStartElement, PsiNamedElement.class);
    if (checkInjections(movedEndElement, movedStartElement))
        return false;
    PsiNamedElement movedParent = null;
    if (namedParentAtEnd == namedParentAtStart)
        movedParent = namedParentAtEnd;
    else if (namedParentAtEnd instanceof XmlAttribute && namedParentAtStart instanceof XmlTag && namedParentAtEnd.getParent() == namedParentAtStart) {
        movedParent = namedParentAtStart;
    } else if (namedParentAtStart instanceof XmlAttribute && namedParentAtEnd instanceof XmlTag && namedParentAtStart.getParent() == namedParentAtEnd) {
        movedParent = namedParentAtEnd;
    }
    if (movedParent == null) {
        return false;
    }
    final TextRange textRange = movedParent.getTextRange();
    if (movedParent instanceof XmlTag) {
        final XmlTag tag = (XmlTag) movedParent;
        PsiElement parent = tag.getParent();
        if (!(parent instanceof XmlTag) && PsiTreeUtil.getChildrenOfType(parent, XmlTag.class).length < 2) {
            // the only top-level tag
            return info.prohibitMove();
        }
        final TextRange valueRange = tag.getValue().getTextRange();
        final int valueStart = valueRange.getStartOffset();
        if (HtmlUtil.isHtmlTag(tag) && (HtmlUtil.isScriptTag(tag) || HtmlUtil.STYLE_TAG_NAME.equals(tag.getName()))) {
            info.toMove = new LineRange(tag);
            int nextLine = down ? info.toMove.endLine : info.toMove.startLine - 1;
            info.toMove2 = new LineRange(nextLine, nextLine + 1);
        }
        if (movedLineStart < valueStart && valueStart + 1 < document.getTextLength()) {
            movedLineStart = updateMovedRegionEnd(document, movedLineStart, valueStart + 1, info, down);
        }
        if (movedLineStart < valueStart) {
            movedLineStart = updateMovedRegionStart(document, movedLineStart, tag.getTextRange().getStartOffset(), info, down);
        }
    } else if (movedParent instanceof XmlAttribute) {
        final int endOffset = textRange.getEndOffset() + 1;
        if (endOffset < document.getTextLength())
            movedLineStart = updateMovedRegionEnd(document, movedLineStart, endOffset, info, down);
        movedLineStart = updateMovedRegionStart(document, movedLineStart, textRange.getStartOffset(), info, down);
    }
    final TextRange moveDestinationRange = new UnfairTextRange(document.getLineStartOffset(info.toMove2.startLine), document.getLineEndOffset(info.toMove2.endLine - 1));
    if (movedParent instanceof XmlAttribute) {
        final XmlTag parent = ((XmlAttribute) movedParent).getParent();
        if (parent != null) {
            final TextRange valueRange = parent.getValue().getTextRange();
            // Do not move attributes out of tags
            if ((down && moveDestinationRange.getEndOffset() >= valueRange.getStartOffset()) || (!down && moveDestinationRange.getStartOffset() <= parent.getTextRange().getStartOffset())) {
                return info.prohibitMove();
            }
        }
    }
    if (down) {
        PsiElement updatedElement = file.findElementAt(moveDestinationRange.getEndOffset());
        if (updatedElement instanceof PsiWhiteSpace)
            updatedElement = PsiTreeUtil.prevLeaf(updatedElement);
        if (updatedElement != null) {
            final PsiNamedElement targetParent = PsiTreeUtil.getParentOfType(updatedElement, movedParent.getClass());
            if (targetParent instanceof XmlTag) {
                if (targetParent == movedParent)
                    return false;
                if (moveTags(info, (XmlTag) movedParent, (XmlTag) targetParent, down))
                    return true;
                final XmlTag tag = (XmlTag) targetParent;
                final int offset = tag.isEmpty() ? tag.getTextRange().getStartOffset() : tag.getValue().getTextRange().getStartOffset();
                updatedMovedIntoEnd(document, info, offset);
                if (tag.isEmpty()) {
                    info.toMove2 = new LineRange(targetParent);
                }
            } else if (targetParent instanceof XmlAttribute) {
                updatedMovedIntoEnd(document, info, targetParent.getTextRange().getEndOffset());
            }
        }
    } else {
        PsiElement updatedElement = file.findElementAt(moveDestinationRange.getStartOffset());
        if (updatedElement instanceof PsiWhiteSpace)
            updatedElement = PsiTreeUtil.nextLeaf(updatedElement);
        if (updatedElement != null) {
            final PsiNamedElement targetParent = PsiTreeUtil.getParentOfType(updatedElement, movedParent.getClass());
            if (targetParent instanceof XmlTag) {
                final XmlTag tag = (XmlTag) targetParent;
                final TextRange tagValueRange = tag.getValue().getTextRange();
                // We need to update destination range to jump over tag start
                final XmlTag[] subtags = tag.getSubTags();
                if ((tagValueRange.contains(movedLineStart) && subtags.length > 0 && subtags[0] == movedParent) || (tagValueRange.getLength() == 0 && tag.getTextRange().intersects(moveDestinationRange))) {
                    final int line = document.getLineNumber(tag.getTextRange().getStartOffset());
                    final LineRange toMove2 = info.toMove2;
                    info.toMove2 = new LineRange(Math.min(line, toMove2.startLine), toMove2.endLine);
                }
                if (targetParent == movedParent)
                    return false;
                if (moveTags(info, (XmlTag) movedParent, (XmlTag) targetParent, down))
                    return true;
            } else if (targetParent instanceof XmlAttribute) {
                final int line = document.getLineNumber(targetParent.getTextRange().getStartOffset());
                final LineRange toMove2 = info.toMove2;
                info.toMove2 = new LineRange(Math.min(line, toMove2.startLine), toMove2.endLine);
            }
        }
    }
    if (movedParent instanceof XmlTag) {
        // it's quite simple after all...
        info.toMove = new LineRange(movedParent);
    }
    return true;
}
Also used : UnfairTextRange(com.intellij.openapi.util.UnfairTextRange) PsiNamedElement(com.intellij.psi.PsiNamedElement) TextRange(com.intellij.openapi.util.TextRange) UnfairTextRange(com.intellij.openapi.util.UnfairTextRange) Document(com.intellij.openapi.editor.Document) PsiElement(com.intellij.psi.PsiElement) PsiWhiteSpace(com.intellij.psi.PsiWhiteSpace)

Example 82 with TextRange

use of com.intellij.openapi.util.TextRange in project intellij-community by JetBrains.

the class TagDeclarationRangeHandler method getDeclarationRange.

@Override
@NotNull
public TextRange getDeclarationRange(@NotNull final PsiElement container) {
    XmlTag xmlTag = (XmlTag) container;
    int endOffset = xmlTag.getTextRange().getStartOffset();
    for (PsiElement child = xmlTag.getFirstChild(); child != null; child = child.getNextSibling()) {
        endOffset = child.getTextRange().getEndOffset();
        if (child instanceof XmlToken) {
            XmlToken token = (XmlToken) child;
            IElementType tokenType = token.getTokenType();
            if (tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END || tokenType == XmlTokenType.XML_TAG_END)
                break;
        }
    }
    return new TextRange(xmlTag.getTextRange().getStartOffset(), endOffset);
}
Also used : IElementType(com.intellij.psi.tree.IElementType) TextRange(com.intellij.openapi.util.TextRange) PsiElement(com.intellij.psi.PsiElement) XmlTag(com.intellij.psi.xml.XmlTag) XmlToken(com.intellij.psi.xml.XmlToken) NotNull(org.jetbrains.annotations.NotNull)

Example 83 with TextRange

use of com.intellij.openapi.util.TextRange in project intellij-community by JetBrains.

the class XmlZenCodingGenerator method computeTemplateKey.

@Nullable
@Override
public String computeTemplateKey(@NotNull CustomTemplateCallback callback) {
    Editor editor = callback.getEditor();
    int currentOffset = editor.getCaretModel().getOffset();
    int startOffset = Math.min(editor.getDocument().getLineStartOffset(editor.getDocument().getLineNumber(currentOffset)), currentOffset);
    CharSequence documentText = editor.getDocument().getCharsSequence();
    PsiElement prevVisibleLeaf = callback.getContext();
    while (prevVisibleLeaf != null) {
        TextRange textRange = prevVisibleLeaf.getTextRange();
        final int endOffset = textRange.getEndOffset();
        if (endOffset <= currentOffset) {
            if (endOffset <= startOffset) {
                break;
            }
            IElementType prevType = prevVisibleLeaf.getNode().getElementType();
            if (prevType == XmlTokenType.XML_TAG_END || prevType == XmlTokenType.XML_EMPTY_ELEMENT_END) {
                startOffset = endOffset;
                break;
            }
        }
        prevVisibleLeaf = PsiTreeUtil.prevVisibleLeaf(prevVisibleLeaf);
    }
    if (startOffset < 0 || currentOffset > documentText.length() || currentOffset < startOffset) {
        Logger.getInstance(getClass()).error("Error while calculating emmet abbreviation. Offset: " + currentOffset + "; Start: " + startOffset, AttachmentFactory.createAttachment(editor.getDocument()));
        return null;
    }
    String key = computeKey(documentText.subSequence(startOffset, currentOffset));
    return !StringUtil.isEmpty(key) && ZenCodingTemplate.checkTemplateKey(key, callback, this) ? key : null;
}
Also used : IElementType(com.intellij.psi.tree.IElementType) TextRange(com.intellij.openapi.util.TextRange) Editor(com.intellij.openapi.editor.Editor) PsiElement(com.intellij.psi.PsiElement) Nullable(org.jetbrains.annotations.Nullable)

Example 84 with TextRange

use of com.intellij.openapi.util.TextRange in project intellij-community by JetBrains.

the class XmlTagTreeHighlightingPass method getHighlights.

public List<HighlightInfo> getHighlights() {
    clearLineMarkers(myEditor);
    final int count = myPairsToHighlight.size();
    final List<HighlightInfo> highlightInfos = new ArrayList<>(count * 2);
    final MarkupModel markupModel = myEditor.getMarkupModel();
    final Color[] baseColors = XmlTagTreeHighlightingUtil.getBaseColors();
    final Color[] colorsForEditor = count > 1 ? toColorsForEditor(baseColors) : new Color[] { myEditor.getColorsScheme().getAttributes(CodeInsightColors.MATCHED_BRACE_ATTRIBUTES).getBackgroundColor() };
    final Color[] colorsForLineMarkers = toColorsForLineMarkers(baseColors);
    final List<RangeHighlighter> newHighlighters = new ArrayList<>();
    assert colorsForEditor.length > 0;
    for (int i = 0; i < count && i < baseColors.length; i++) {
        Pair<TextRange, TextRange> pair = myPairsToHighlight.get(i);
        if (pair.first == null && pair.second == null) {
            continue;
        }
        Color color = colorsForEditor[i];
        if (color == null) {
            continue;
        }
        if (pair.first != null && !pair.first.isEmpty()) {
            highlightInfos.add(createHighlightInfo(color, pair.first));
        }
        if (pair.second != null && !pair.second.isEmpty()) {
            highlightInfos.add(createHighlightInfo(color, pair.second));
        }
        final int start = pair.first != null ? pair.first.getStartOffset() : pair.second.getStartOffset();
        final int end = pair.second != null ? pair.second.getEndOffset() : pair.first.getEndOffset();
        final Color lineMarkerColor = colorsForLineMarkers[i];
        if (count > 1 && lineMarkerColor != null && start != end) {
            final RangeHighlighter highlighter = createHighlighter(markupModel, new TextRange(start, end), lineMarkerColor);
            newHighlighters.add(highlighter);
        }
    }
    myEditor.putUserData(TAG_TREE_HIGHLIGHTERS_IN_EDITOR_KEY, newHighlighters);
    return highlightInfos;
}
Also used : ArrayList(java.util.ArrayList) HighlightInfo(com.intellij.codeInsight.daemon.impl.HighlightInfo) TextRange(com.intellij.openapi.util.TextRange) DocumentMarkupModel(com.intellij.openapi.editor.impl.DocumentMarkupModel)

Example 85 with TextRange

use of com.intellij.openapi.util.TextRange in project intellij-community by JetBrains.

the class XmlTagTreeHighlightingPass method getEndTagRange.

@Nullable
private static TextRange getEndTagRange(ASTNode tagNode) {
    final ASTNode endTagStart = XmlChildRole.CLOSING_TAG_START_FINDER.findChild(tagNode);
    if (endTagStart == null) {
        return null;
    }
    ASTNode endTagEnd = endTagStart;
    while (endTagEnd != null && endTagEnd.getElementType() != XmlTokenType.XML_TAG_END) {
        endTagEnd = endTagEnd.getTreeNext();
    }
    if (endTagEnd == null) {
        return null;
    }
    return new TextRange(endTagStart.getStartOffset(), endTagEnd.getTextRange().getEndOffset());
}
Also used : ASTNode(com.intellij.lang.ASTNode) TextRange(com.intellij.openapi.util.TextRange) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

TextRange (com.intellij.openapi.util.TextRange)1314 PsiElement (com.intellij.psi.PsiElement)261 NotNull (org.jetbrains.annotations.NotNull)237 Nullable (org.jetbrains.annotations.Nullable)167 Document (com.intellij.openapi.editor.Document)132 ArrayList (java.util.ArrayList)117 Project (com.intellij.openapi.project.Project)96 PsiFile (com.intellij.psi.PsiFile)96 ASTNode (com.intellij.lang.ASTNode)95 Editor (com.intellij.openapi.editor.Editor)75 PsiReference (com.intellij.psi.PsiReference)54 VirtualFile (com.intellij.openapi.vfs.VirtualFile)51 IElementType (com.intellij.psi.tree.IElementType)48 IncorrectOperationException (com.intellij.util.IncorrectOperationException)48 Pair (com.intellij.openapi.util.Pair)47 HighlightInfo (com.intellij.codeInsight.daemon.impl.HighlightInfo)33 ProperTextRange (com.intellij.openapi.util.ProperTextRange)32 FoldingDescriptor (com.intellij.lang.folding.FoldingDescriptor)31 XmlTag (com.intellij.psi.xml.XmlTag)31 List (java.util.List)31