How to override standard completion in XML file?
Standard (non-DTD or schema) completion in XML file is interfering with my
custom completion. For example, it suggests tags where they could not go,
according to the custom XML format my plugin provides completions for. Is there
a way to disable this completion from within my plugin, for certain .xml files?
Is there some workaround I could provide until this works?
Please sign in to leave a comment.
Well, once you have your own CompletionData instance registered with your file(-type), you
should be able override its completeReference() method and filter out what you don't want.
Sascha
Thank you very much. I didn't even see it.
Sascha Weinreuter wrote:
How to add HTML attribute completion variants correctly?
If register the CompletionData that extends the HtmlCompletionData class and overrides the method:
public void completeReference(PsiReference psiReference, Set set, CompletionContext completionContext, PsiElement psiElement) {
super.completeReference(psiReference, set, completionContext, psiElement);
PsiElement element = psiReference.getElement();
if (element instanceof XmlAttribute) {
set.add(new LookupItem(new Key("myAttribute"), "myAttribute"));
}
}
then completion dialog (that appears if press Ctrl-Space in the HTML file to complete tag attribute) contain the "myAttribute" also.
Please explain what parameters pass to the LookupItem constructor. Is the second parameter is variant label?
I don't know if you should extend HtmlCompletionData. I extend
CompletionData:
class GxpCompletionData extends CompletionData {
{
declareFinalScope(XmlElement.class);
CompletionVariant cv3 = new CompletionVariant(new ElementFilter() {
public boolean isAcceptable(Object object, PsiElement psiElement) {
if (!(psiElement.getContainingFile() instanceof XmlFile)) {
return false;
}
if (psiElement instanceof XmlToken) {
XmlToken xmlToken = (XmlToken) psiElement;
if (xmlToken.getTokenType() == XmlTokenType
.XML_ATTRIBUTE_VALUE_TOKEN) {
return true;
}
}
return false;
}
public boolean isClassAcceptable(Class aClass) {
return true;
}
});
cv3.includeScopeClass(XmlElement.class, true);
cv3.addCompletionFilterOnElement(... filter which accepts xml ...);
cv3.addCompletion(new ValueContextGetter(), 0);
registerVariant(cv3);
}
private static class ValueContextGetter implements ContextGetter {
public Object[] get(PsiElement psiElement, CompletionContext context) {
XmlTag tag = PsiTreeUtil.getParentOfType(psiElement, XmlTag.class);
assert tag != null;
XmlAttribute attr = PsiTreeUtil.getParentOfType(psiElement,
XmlAttribute.class);
assert attr != null;
...
return new String[] { expectedName };
}
}
I then call CompletionUtil.registerCompletionData for xml type and an
instance of my completiondata subclass.
You shouldn't get frustrated, completion took me a long time to get
working, with help from Dmitry and Sascha, but it paid off.
Alexei wrote:
what is the best manner to register a new CompletionData?
I add it in int method of my plugin
public void initComponent() {
System.out.println("init " + this.getComponentName());
CompletionUtil.registerCompletionData(StdFileTypes.JSP,new JsfCompletior());
}
the CompletiorVariant is registed right but is never called even if the ElementFilter is a dummy implementation thath always returns true...
In case anyone else stumbles upon this:
it's not possible to register more than one CompletionData per FileType.. now I have to throw everything I wanted to implement in separate classes into one big pile :(