void (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, ">")); } } }); }