public static void insertIncompleteTag(char completionChar,
                                          final Editor editor,
                                          XmlTag tag) {
    XmlTag originalElement = CompletionUtil.getOriginalElement(tag);
    XmlElementDescriptor descriptor = originalElement != null ? originalElement.getDescriptor() : tag.getDescriptor();
    if (descriptor == null) return;
    final Project project = editor.getProject();
    TemplateManager templateManager = TemplateManager.getInstance(project);
    Template template = templateManager.createTemplate("", "");

    template.setToIndent(true);

    // temp code
    PsiFile containingFile = tag.getContainingFile();
    boolean fileHasHtml = HtmlUtil.hasHtml(containingFile);
    // Non-html code like Pug embedded in HTML template
    if (fileHasHtml && !tag.getLanguage().isKindOf(XMLLanguage.INSTANCE)) return;
    boolean htmlCode = fileHasHtml || HtmlUtil.supportsXmlTypedHandlers(containingFile);
    template.setToReformat(!htmlCode);

    StringBuilder indirectRequiredAttrs = addRequiredAttributes(descriptor, tag, template, containingFile);
    final boolean chooseAttributeName = addTail(completionChar, descriptor, htmlCode, tag, template, indirectRequiredAttrs);

    templateManager.startTemplate(editor, template, new TemplateEditingAdapter() {
      private RangeMarker myAttrValueMarker;

      @Override
      public void waitingForInput(Template template) {
        int offset = editor.getCaretModel().getOffset();
        myAttrValueMarker = editor.getDocument().createRangeMarker(offset + 1, offset + 4);
      }

      @Override
      public void templateFinished(final @NotNull Template template, boolean brokenOff) {
        final int offset = editor.getCaretModel().getOffset();

        if (chooseAttributeName && offset > 0) {
          char c = editor.getDocument().getCharsSequence().charAt(offset - 1);
          if (c == '/' || (c == ' ' && brokenOff)) {
            WriteCommandAction.writeCommandAction(project).run(() -> editor.getDocument().replaceString(offset, offset + 3, ">"));
          }
        }
      }

      @Override
      public void templateCancelled(final Template template) {
        if (myAttrValueMarker == null) {
          return;
        }

        if (UndoManager.getInstance(project).isUndoOrRedoInProgress()) {
          return;
        }

        if (chooseAttributeName && myAttrValueMarker.isValid()) {
          final int startOffset = myAttrValueMarker.getStartOffset();
          final int endOffset = myAttrValueMarker.getEndOffset();
          WriteCommandAction.writeCommandAction(project).run(() -> editor.getDocument().replaceString(startOffset, endOffset, ">"));
        }
      }
    });
  }
public static void insertIncompleteTag(char completionChar,
                                          final Editor editor,
                                          XmlTag tag)