void (final @NotNull Project project, final @NotNull Editor editor, final @NotNull PsiFile file) { if (!EditorModificationUtil.checkModificationAllowed(editor)) return; try { final XmlTag contextTag = getContextTag(editor, file); if (contextTag == null) { throw new CommonRefactoringUtil.RefactoringErrorHintException("Caret should be positioned inside a tag"); } XmlElementDescriptor currentTagDescriptor = contextTag.getDescriptor(); assert currentTagDescriptor != null; final XmlElementDescriptor[] descriptors = currentTagDescriptor.getElementsDescriptors(contextTag); Arrays.sort(descriptors, Comparator.comparing(PsiMetaData::getName)); Consumer<XmlElementDescriptor> consumer = (selected) -> WriteCommandAction.writeCommandAction(project, file).withName(XmlBundle.message("generate.xml.tag")).run(() -> { if (selected == null) return; XmlTag newTag = createTag(contextTag, selected); PsiElement anchor = getAnchor(contextTag, editor, selected); if (anchor == null) { // insert it in the cursor position int offset = editor.getCaretModel().getOffset(); Document document = editor.getDocument(); document.insertString(offset, newTag.getText()); PsiDocumentManager.getInstance(project).commitDocument(document); newTag = PsiTreeUtil.getParentOfType(file.findElementAt(offset + 1), XmlTag.class, false); } else { newTag = (XmlTag)contextTag.addAfter(newTag, anchor); } if (newTag != null) { generateTag(newTag, editor); } }); if (ApplicationManager.getApplication().isUnitTestMode()) { XmlElementDescriptor descriptor = ContainerUtil.find(descriptors, xmlElementDescriptor -> xmlElementDescriptor.getName().equals(TEST_THREAD_LOCAL.get())); consumer.consume(descriptor); } else { JBPopupFactory.getInstance() .createPopupChooserBuilder(List.of(descriptors)) .setRenderer(new MyListCellRenderer()) .setTitle(XmlBundle.message("choose.tag.name")) .setItemChosenCallback(consumer) .setNamerForFiltering(o -> o.getName()) .createPopup() .showInBestPositionFor(editor); } } catch (CommonRefactoringUtil.RefactoringErrorHintException e) { HintManager.getInstance().showErrorHint(editor, e.getMessage()); } }