diff --git a/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java b/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java index 95bfae259b38..b2f7936299eb 100644 --- a/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java +++ b/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java @@ -52,13 +52,10 @@ public class XmlSmartCompletionProvider { if (subTag == tag) { break; } - XmlElementDescriptor childDescriptor = subTag.getDescriptor(); - if (childDescriptor != null) { - dfa.transition(childDescriptor, subTag); - } + dfa.transition(subTag); } List elements = dfa.getPossibleElements(); - for (XmlElementDescriptor elementDescriptor : elements) { + for (XmlElementDescriptor elementDescriptor: elements) { addElementToResult(elementDescriptor, result); } } diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFA.java b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFA.java index 0c672f506f36..448ce5214f3c 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFA.java +++ b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFA.java @@ -29,7 +29,7 @@ public abstract class XmlContentDFA { public abstract List getPossibleElements(); - public abstract void transition(@NotNull XmlElementDescriptor element, XmlTag xmlTag); + public abstract void transition(XmlTag xmlTag); @Nullable public static XmlContentDFA getContentDFA(XmlTag parentTag) { diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFAImpl.java b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFAImpl.java index 1faee65bf693..3c4b859aa3f1 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFAImpl.java +++ b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFAImpl.java @@ -90,8 +90,11 @@ class XmlContentDFAImpl extends XmlContentDFA { } @Override - public void transition(@NotNull XmlElementDescriptor element, XmlTag xmlTag) { - doTransition(element); + public void transition(XmlTag xmlTag) { + XmlElementDescriptor descriptor = xmlTag.getDescriptor(); + if (descriptor != null) { + doTransition(descriptor); + } } private Result doTransition(@NotNull XmlElementDescriptor element) { diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/XsContentDFA.java b/xml/impl/src/com/intellij/psi/impl/source/xml/XsContentDFA.java index 53d709b86a5e..8fc66ab1361d 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/xml/XsContentDFA.java +++ b/xml/impl/src/com/intellij/psi/impl/source/xml/XsContentDFA.java @@ -119,7 +119,7 @@ class XsContentDFA extends XmlContentDFA { } @Override - public void transition(@NotNull XmlElementDescriptor element, XmlTag xmlTag) { + public void transition(XmlTag xmlTag) { myContentModel.oneTransition(createQName(xmlTag), myState, myHandler); } diff --git a/xml/impl/src/com/intellij/xml/actions/GenerateXmlTagAction.java b/xml/impl/src/com/intellij/xml/actions/GenerateXmlTagAction.java index 0ba9355868ab..1f5c9fde3008 100644 --- a/xml/impl/src/com/intellij/xml/actions/GenerateXmlTagAction.java +++ b/xml/impl/src/com/intellij/xml/actions/GenerateXmlTagAction.java @@ -40,6 +40,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.XmlElementFactory; import com.intellij.psi.impl.source.tree.Factory; import com.intellij.psi.impl.source.tree.LeafElement; +import com.intellij.psi.impl.source.xml.XmlContentDFA; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.xml.*; import com.intellij.refactoring.util.CommonRefactoringUtil; @@ -91,16 +92,9 @@ public class GenerateXmlTagAction extends SimpleCodeInsightAction { protected void run() { if (selected == null) return; XmlTag newTag = createTag(contextTag, selected); - int offset = editor.getCaretModel().getOffset(); - PsiElement element = file.findElementAt(offset); - if (element != null) { - XmlText xmlText = PsiTreeUtil.getParentOfType(element, XmlText.class); - if (xmlText != null) { - } - } - - newTag = contextTag.addSubTag(newTag, false); + PsiElement anchor = getAnchor(contextTag, editor, selected); + newTag = anchor == null ? contextTag.addSubTag(newTag, true) : (XmlTag)contextTag.addAfter(newTag, anchor); generateTag(newTag); } }.execute(); @@ -135,6 +129,34 @@ public class GenerateXmlTagAction extends SimpleCodeInsightAction { } } + @Nullable + private static PsiElement getAnchor(XmlTag contextTag, Editor editor, XmlElementDescriptor selected) { + XmlContentDFA contentDFA = XmlContentDFA.getContentDFA(contextTag); + PsiElement anchor = null; + int offset = editor.getCaretModel().getOffset(); + if (contentDFA != null) { + for (XmlTag subTag : contextTag.getSubTags()) { + if (contentDFA.getPossibleElements().contains(selected)) { + if (subTag.getTextOffset() > offset) { + break; + } + anchor = subTag; + } + contentDFA.transition(subTag); + } + } + if (anchor == null) { // insert it at caret position + PsiElement[] children = contextTag.getChildren(); + for (PsiElement child : children) { + if (child.getTextOffset() > offset) { + break; + } + anchor = child; + } + } + return anchor; + } + public static void generateTag(XmlTag newTag) { newTag = generateRaw(newTag); newTag = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(newTag);