@Override public void addTagNameVariants(List<LookupElement> elements, @NotNull XmlTag tag, String prefix) { final List<String> namespaces; if(prefix.isEmpty()) { namespaces = new ArrayList<>(Arrays.asList(tag.knownNamespaces())); namespaces.add(XmlUtil.EMPTY_URI); // empty namespace } else { namespaces = new ArrayList<>(Collections.singletonList(tag.getNamespace())); } PsiFile psiFile = tag.getContainingFile(); XmlExtension xmlExtension = XmlExtension.getExtension(psiFile); List<String> nsInfo = new ArrayList<>(); List<XmlElementDescriptor> variants = TagNameVariantCollector.getTagDescriptors(tag, namespaces, nsInfo); if(variants.isEmpty() && psiFile instanceof XmlFile && ((XmlFile) psiFile).getRootTag() == tag) { getRootTagsVariants(tag, elements); return; } final Set<String> visited = new HashSet<>(); for(int i = 0; i < variants.size(); i++) { XmlElementDescriptor descriptor = variants.get(i); String qname = descriptor.getName(tag); if(!visited.add(qname)) { continue; } if(!prefix.isEmpty() && qname.startsWith(prefix + ":")) { qname = qname.substring(prefix.length() + 1); } PsiElement declaration = descriptor.getDeclaration(); if(declaration != null && !declaration.isValid()) { LOG.error(descriptor + " contains invalid declaration: " + declaration); } LookupElementBuilder lookupElement = declaration == null ? LookupElementBuilder.create(qname) : LookupElementBuilder.create(declaration, qname); final int separator = qname.indexOf(':'); if(separator > 0) { lookupElement = lookupElement.withLookupString(qname.substring(separator + 1)); } String ns = nsInfo.get(i); if(StringUtil.isNotEmpty(ns)) { lookupElement = lookupElement.withTypeText(ns, true); } if(descriptor instanceof PsiPresentableMetaData) { lookupElement = lookupElement.withIcon(((PsiPresentableMetaData) descriptor).getIcon()); } if(xmlExtension.useXmlTagInsertHandler()) { lookupElement = lookupElement.withInsertHandler(XmlTagInsertHandler.INSTANCE); } lookupElement = lookupElement.withCaseSensitivity(!(descriptor instanceof HtmlElementDescriptorImpl)); elements.add(PrioritizedLookupElement.withPriority(lookupElement, separator > 0 ? 0 : 1)); } }