Collection<LookupElement> (final XPathNodeTest element) { if (!element.isNameTest()) { return Collections.emptyList(); } final PrefixedName prefixedName = element.getQName(); assert prefixedName != null; final String canonicalText = prefixedName.toString(); final String suffix = canonicalText.substring(canonicalText.indexOf(INTELLIJ_IDEA_RULEZ)); final XPathAxisSpecifier axisSpecifier = element.getStep().getAxisSpecifier(); final ContextProvider contextProvider = ContextProvider.getContextProvider(element); final XmlElement context = contextProvider.getContextElement(); final boolean insidePrefix = suffix.contains(INTELLIJ_IDEA_RULEZ + ":"); final Set<LookupElement> list = new HashSet<>(); addNameCompletions(contextProvider, element, list); final String namespacePrefix = prefixedName.getPrefix(); if (namespacePrefix == null || insidePrefix) { addNamespaceCompletions(contextProvider.getNamespaceContext(), list, context); } final XPathNodeTest.PrincipalType principalType = addContextNames(element, contextProvider, prefixedName, list); if (namespacePrefix == null && !insidePrefix) { if (axisSpecifier == null || axisSpecifier.isDefaultAxis()) { list.addAll(getAxisCompletions()); // wow, this code sux. find a better implementation PsiElement sibling = element.getParent().getPrevSibling(); while (sibling instanceof PsiWhiteSpace) { sibling = sibling.getPrevSibling(); } boolean check = sibling != null; if (!check) { XPathLocationPath lp = null; do { lp = PsiTreeUtil.getParentOfType(lp == null ? element : lp, XPathLocationPath.class, true); } while (lp != null && lp.getPrevSibling() == null); if (lp != null) { sibling = lp.getPrevSibling(); } } if (sibling instanceof XPathToken && XPathTokenTypes.PATH_OPS.contains(((XPathToken)sibling).getTokenType())) { // xx/yy<caret> : prevSibl = / } else { list.addAll(getFunctionCompletions(element)); list.addAll(getVariableCompletions(element)); } } if (principalType == XPathNodeTest.PrincipalType.ELEMENT && prefixedName.getPrefix() == null) { list.addAll(getNodeTypeCompletions(element)); } } return list; }