zen coding works in empty files and end-of-file, tests
authorEugene Kudelevsky <Eugene.Kudelevsky@jetbrains.com>
Wed, 7 Apr 2010 14:18:59 +0000 (18:18 +0400)
committerEugene Kudelevsky <Eugene.Kudelevsky@jetbrains.com>
Wed, 7 Apr 2010 14:18:59 +0000 (18:18 +0400)
xml/impl/src/com/intellij/codeInsight/completion/XmlSmartEnterProcessor.java

index be20f7683e299d306a81b4de6a0eca8abfc27a1a..b8bc8e1004723edb131702eef00ed73e8a800b43 100644 (file)
@@ -42,99 +42,107 @@ public class XmlSmartEnterProcessor extends SmartEnterProcessor {
   private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.XmlSmartEnterProcessor");
 
   public boolean process(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile psiFile) {
   private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.XmlSmartEnterProcessor");
 
   public boolean process(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile psiFile) {
+    if (!completeEndTag(project, editor, psiFile)) {
+      return XmlZenCodingTemplate.startZenCoding(editor, psiFile, null);
+    }
+    return true;
+  }
+
+  private boolean completeEndTag(Project project, Editor editor, PsiFile psiFile) {
     final PsiElement atCaret = getStatementAtCaret(editor, psiFile);
     XmlTag tagAtCaret = PsiTreeUtil.getParentOfType(atCaret, XmlTag.class);
     final PsiElement atCaret = getStatementAtCaret(editor, psiFile);
     XmlTag tagAtCaret = PsiTreeUtil.getParentOfType(atCaret, XmlTag.class);
-    if (tagAtCaret != null) {
-      try {
-        final ASTNode emptyTagEnd = XmlChildRole.EMPTY_TAG_END_FINDER.findChild(tagAtCaret.getNode());
-        final ASTNode endTagEnd = XmlChildRole.START_TAG_END_FINDER.findChild(tagAtCaret.getNode());
-        if (emptyTagEnd != null || endTagEnd != null) {
-          return XmlZenCodingTemplate.startZenCoding(editor, psiFile, null);
-        }
+    if (tagAtCaret == null) {
+      return false;
+    }
+    try {
+      final ASTNode emptyTagEnd = XmlChildRole.EMPTY_TAG_END_FINDER.findChild(tagAtCaret.getNode());
+      final ASTNode endTagEnd = XmlChildRole.START_TAG_END_FINDER.findChild(tagAtCaret.getNode());
+      if (emptyTagEnd != null || endTagEnd != null) {
+        return false;
+      }
 
 
-        int insertionOffset = tagAtCaret.getTextRange().getEndOffset();
-        Document doc = editor.getDocument();
-        int caretAt = editor.getCaretModel().getOffset();
-        final CharSequence text = doc.getCharsSequence();
-        final int probableCommaOffset = CharArrayUtil.shiftForward(text, insertionOffset, " \t");
-        final PsiElement siebling = tagAtCaret.getNextSibling();
-        int caretTo = caretAt;
-        char ch;
-
-        if (caretAt < probableCommaOffset) {
-          final XmlAttribute xmlAttribute = PsiTreeUtil.getParentOfType(atCaret, XmlAttribute.class, false, XmlTag.class);
-
-          CharSequence tagNameText = null;
-          if (xmlAttribute != null) {
-            final ASTNode node = tagAtCaret.getNode();
-            if (node != null) {
-              final ASTNode tagName = XmlChildRole.START_TAG_NAME_FINDER.findChild(node);
-              if (tagName != null) {
-                tagNameText = tagName.getText();
-              }
+      int insertionOffset = tagAtCaret.getTextRange().getEndOffset();
+      Document doc = editor.getDocument();
+      int caretAt = editor.getCaretModel().getOffset();
+      final CharSequence text = doc.getCharsSequence();
+      final int probableCommaOffset = CharArrayUtil.shiftForward(text, insertionOffset, " \t");
+      final PsiElement siebling = tagAtCaret.getNextSibling();
+      int caretTo = caretAt;
+      char ch;
+
+      if (caretAt < probableCommaOffset) {
+        final XmlAttribute xmlAttribute = PsiTreeUtil.getParentOfType(atCaret, XmlAttribute.class, false, XmlTag.class);
+
+        CharSequence tagNameText = null;
+        if (xmlAttribute != null) {
+          final ASTNode node = tagAtCaret.getNode();
+          if (node != null) {
+            final ASTNode tagName = XmlChildRole.START_TAG_NAME_FINDER.findChild(node);
+            if (tagName != null) {
+              tagNameText = tagName.getText();
             }
             }
-
-            final XmlAttributeValue valueElement = xmlAttribute.getValueElement();
-            final TextRange textRange = xmlAttribute.getTextRange();
-            caretAt = valueElement == null ? textRange.getStartOffset() : getClosingQuote(xmlAttribute).length() == 0 ? textRange.getEndOffset() : caretAt;
           }
 
           }
 
-          if (tagNameText == null) {
-            tagNameText = text.subSequence(tagAtCaret.getTextRange().getStartOffset() + 1, caretAt);
-          }
+          final XmlAttributeValue valueElement = xmlAttribute.getValueElement();
+          final TextRange textRange = xmlAttribute.getTextRange();
+          caretAt = valueElement == null ? textRange.getStartOffset() : getClosingQuote(xmlAttribute).length() == 0 ? textRange.getEndOffset() : caretAt;
+        }
 
 
-          final PsiElement element = psiFile.findElementAt(probableCommaOffset);
-          final XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class);
-          final CharSequence text2insert = getClosingPart(xmlAttribute, tagAtCaret, false);
+        if (tagNameText == null) {
+          tagNameText = text.subSequence(tagAtCaret.getTextRange().getStartOffset() + 1, caretAt);
+        }
 
 
-          if (tag != null && tag.getTextRange().getStartOffset() == probableCommaOffset) {
-            doc.insertString(caretAt, text2insert);
-            if (shouldInsertClosingTag(xmlAttribute, tagAtCaret)) {
-              doc.insertString(tag.getTextRange().getEndOffset() + text2insert.length(), "</" + tagAtCaret.getName() + ">");
-            }
+        final PsiElement element = psiFile.findElementAt(probableCommaOffset);
+        final XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class);
+        final CharSequence text2insert = getClosingPart(xmlAttribute, tagAtCaret, false);
 
 
-            caretTo = tag.getTextRange().getEndOffset() + text2insert.length();
+        if (tag != null && tag.getTextRange().getStartOffset() == probableCommaOffset) {
+          doc.insertString(caretAt, text2insert);
+          if (shouldInsertClosingTag(xmlAttribute, tagAtCaret)) {
+            doc.insertString(tag.getTextRange().getEndOffset() + text2insert.length(), "</" + tagAtCaret.getName() + ">");
           }
           }
-          else {
-            doc.insertString(caretAt, text2insert);
-            if (shouldInsertClosingTag(xmlAttribute, tagAtCaret)) {
-              doc.insertString(probableCommaOffset + text2insert.length(), "</" + tagNameText + ">");
-            }
 
 
-            caretTo = probableCommaOffset + text2insert.length();
-          }
+          caretTo = tag.getTextRange().getEndOffset() + text2insert.length();
         }
         }
-        else if (siebling instanceof XmlTag && siebling.getTextRange().getStartOffset() == caretAt) {
-          final XmlAttribute xmlAttribute = PsiTreeUtil.getParentOfType(atCaret, XmlAttribute.class, false, XmlTag.class);
-          final CharSequence text2insert = getClosingPart(xmlAttribute, tagAtCaret, false);
-
+        else {
           doc.insertString(caretAt, text2insert);
           if (shouldInsertClosingTag(xmlAttribute, tagAtCaret)) {
           doc.insertString(caretAt, text2insert);
           if (shouldInsertClosingTag(xmlAttribute, tagAtCaret)) {
-            doc.insertString(siebling.getTextRange().getEndOffset() + text2insert.length(), "</" + tagAtCaret.getName() + ">");
+            doc.insertString(probableCommaOffset + text2insert.length(), "</" + tagNameText + ">");
           }
 
           }
 
-          caretTo = siebling.getTextRange().getEndOffset() + text2insert.length();
+          caretTo = probableCommaOffset + text2insert.length();
         }
         }
-        else if (probableCommaOffset >= text.length() || ((ch = text.charAt(probableCommaOffset)) != '/' && ch != '>')) {
-          final XmlAttribute xmlAttribute = PsiTreeUtil.getParentOfType(atCaret, XmlAttribute.class, false, XmlTag.class);
-          final CharSequence text2insert = getClosingPart(xmlAttribute, tagAtCaret, true);
+      }
+      else if (siebling instanceof XmlTag && siebling.getTextRange().getStartOffset() == caretAt) {
+        final XmlAttribute xmlAttribute = PsiTreeUtil.getParentOfType(atCaret, XmlAttribute.class, false, XmlTag.class);
+        final CharSequence text2insert = getClosingPart(xmlAttribute, tagAtCaret, false);
 
 
-          doc.insertString(insertionOffset, text2insert);
-          caretTo = insertionOffset + text2insert.length();
+        doc.insertString(caretAt, text2insert);
+        if (shouldInsertClosingTag(xmlAttribute, tagAtCaret)) {
+          doc.insertString(siebling.getTextRange().getEndOffset() + text2insert.length(), "</" + tagAtCaret.getName() + ">");
         }
 
         }
 
-        if (isUncommited(project)) {
-          commit(editor);
-          tagAtCaret = PsiTreeUtil.getParentOfType(getStatementAtCaret(editor, psiFile), XmlTag.class);
-          editor.getCaretModel().moveToOffset(caretTo);
-        }
+        caretTo = siebling.getTextRange().getEndOffset() + text2insert.length();
+      }
+      else if (probableCommaOffset >= text.length() || ((ch = text.charAt(probableCommaOffset)) != '/' && ch != '>')) {
+        final XmlAttribute xmlAttribute = PsiTreeUtil.getParentOfType(atCaret, XmlAttribute.class, false, XmlTag.class);
+        final CharSequence text2insert = getClosingPart(xmlAttribute, tagAtCaret, true);
 
 
-        reformat(tagAtCaret);
-        commit(editor);
+        doc.insertString(insertionOffset, text2insert);
+        caretTo = insertionOffset + text2insert.length();
       }
       }
-      catch (IncorrectOperationException e) {
-        LOG.error(e);
+
+      if (isUncommited(project)) {
+        commit(editor);
+        tagAtCaret = PsiTreeUtil.getParentOfType(getStatementAtCaret(editor, psiFile), XmlTag.class);
+        editor.getCaretModel().moveToOffset(caretTo);
       }
       }
+
+      reformat(tagAtCaret);
+      commit(editor);
+    }
+    catch (IncorrectOperationException e) {
+      LOG.error(e);
     }
     return true;
   }
     }
     return true;
   }