blob: 51e93d81c1cbf5fcae3a1af3dffed49a7fb8f468 [file] [log] [blame]
package org.jetbrains.android.formatter;
import com.intellij.formatting.FormattingDocumentModel;
import com.intellij.formatting.WrapType;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.formatter.FormatterUtil;
import com.intellij.psi.formatter.xml.XmlPolicy;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlTag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Eugene.Kudelevsky
*/
public class AndroidXmlPolicy extends XmlPolicy {
private final AndroidXmlCodeStyleSettings.MySettings myCustomSettings;
public AndroidXmlPolicy(CodeStyleSettings settings,
AndroidXmlCodeStyleSettings.MySettings customSettings,
FormattingDocumentModel documentModel) {
super(settings, documentModel);
myCustomSettings = customSettings;
}
@Override
public WrapType getWrappingTypeForTagBegin(XmlTag tag) {
final PsiElement element = getNextSiblingElement(tag);
if (element instanceof XmlTag && insertLineBreakBeforeTag((XmlTag)element)) {
return WrapType.NORMAL;
}
return super.getWrappingTypeForTagBegin(tag);
}
@Override
public int getAttributesWrap() {
return myCustomSettings.WRAP_ATTRIBUTES;
}
@Override
public boolean insertLineBreakBeforeFirstAttribute(XmlAttribute attribute) {
if (!myCustomSettings.INSERT_LINE_BREAK_BEFORE_FIRST_ATTRIBUTE ||
attribute.isNamespaceDeclaration()) {
return false;
}
return attribute.getParent().getAttributes().length > 1;
}
@Override
public boolean insertLineBreakAfterLastAttribute(XmlAttribute attribute) {
if (!myCustomSettings.INSERT_LINE_BREAK_AFTER_LAST_ATTRIBUTE) {
return false;
}
return attribute.getParent().getAttributes().length > 1;
}
@Nullable
protected static PsiElement getPrevSiblingElement(@NotNull PsiElement element) {
final PsiElement prev = element.getPrevSibling();
ASTNode prevNode = SourceTreeToPsiMap.psiElementToTree(prev);
while (prevNode != null && FormatterUtil.containsWhiteSpacesOnly(prevNode)) {
prevNode = prevNode.getTreePrev();
}
return SourceTreeToPsiMap.treeElementToPsi(prevNode);
}
@Nullable
protected static PsiElement getNextSiblingElement(@NotNull PsiElement element) {
final PsiElement next = element.getNextSibling();
ASTNode nextNode = SourceTreeToPsiMap.psiElementToTree(next);
while (nextNode != null && FormatterUtil.containsWhiteSpacesOnly(nextNode)) {
nextNode = nextNode.getTreeNext();
}
return SourceTreeToPsiMap.treeElementToPsi(nextNode);
}
}