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;
}
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);
}
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;
}
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;
}
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());
}
Aggregations