HTML Attribute completion

I'm trying to extend the HTML editor: add custom attributes to the element attributes completion list (some HTML elements may have custom attributes). I have performed the actions below:
1. Registered the reference provider:
ReferenceProvidersRegistry registry = ReferenceProvidersRegistry.getInstance(_project);
registry.registerReferenceProvider(XmlElement.class, new MyAttributeProvider(_project));

2. Added the MyAttributeProvider class that implements PsiReferenceProvider and implemented the getReferencesByElement(PsiElement) method which returns one element array with MyReference (implements PsiReference).

If I press Ctrl-space in the HTML editor to show element attribute variants then MyAttributeProvider.getReferencesByElement(PsiElement) is called. Then MyReference.getRangeInElement() is called and standard html attributes menu called (so my code doesn't take effect).

What's wrong? Do I need to register custom language type? And please shed light which PsiReference methods are called on code completion.

9 comments

Alexei wrote:

I'm trying to extend the HTML editor: add custom attributes to the element
attributes completion list (some HTML elements may have custom attributes). I
have performed the actions below: 1. Registered the reference provider:
ReferenceProvidersRegistry registry =
ReferenceProvidersRegistry.getInstance(_project);
registry.registerReferenceProvider(XmlElement.class, new
MyAttributeProvider(_project));

2. Added the MyAttributeProvider class that implements PsiReferenceProvider
and implemented the getReferencesByElement(PsiElement) method which returns
one element array with MyReference (implements PsiReference).

If I press Ctrl-space in the HTML editor to show element attribute variants
then MyAttributeProvider.getReferencesByElement(PsiElement) is called. Then
MyReference.getRangeInElement() is called and standard html attributes menu
called (so my code doesn't take effect).

What's wrong? Do I need to register custom language type? And please shed
light which PsiReference methods are called on code completion.


Completion uses getVariants(). Is that called? If getRangeInElement is called
but getVariants() isn't, maybe your getRangeInElement is incorrect. Does it
correctly return the range within the element returned by getElement() (normally
TextRange.from(0, getElement().getTextRange().getLength()))?

0

Can you please describe how you were able to register the ReferenceProvidersRegistry ?

I'm trying something similar to what your doing but ReferenceProvidersRegistry registry = ReferenceProvidersRegistry.getInstance(project); always returns null.

Thanks.

0

I call from projectOpened in my ProjectComponent:

ReferenceProvidersRegistry registry = ReferenceProvidersRegistry
.getInstance(project);

Are you sure you're not passing null project? This has never failed for me.

Hugo Palma wrote:

Can you please describe how you were able to register the ReferenceProvidersRegistry ?

I'm trying something similar to what your doing but ReferenceProvidersRegistry registry = ReferenceProvidersRegistry.getInstance(project); always returns null.

Thanks.

0

Did you add idea.jar to your module classpath rather than to the IDEA JDK? That's the most
common source for this kind of misbehavior. Be sure to clean the sandbox after removing
the jar from the classpath.

Sascha

0

Something is wrong if register the PsiReferenceProvider for XML attribute values:
ReferenceProvidersRegistry registry = ReferenceProvidersRegistry.getInstance(_project);
registry.registerReferenceProvider(XmlAttributeValue.class, new AttributeValueProvider());

The AttributeValueProvider.getReferencesByElement() method is called if press Control-Space in the end of this line:
<span id="main"
And I see in logs that PsiElement passed to the getReferencesByElement() method is "main".

Maybe do I need to register the provider using the registerXmlAttributeValueReferenceProvider() method (but I can't try it because I don't know what to pass as 1st and 2nd arguments)?

0

Yep, that was it, i had idea.jar in my module classpath. I works now.

Thanks.

0

I'm not being able to do something similar. I can see that getVariants method is invoked, but still nothing shows up in the autocomplete list. Also the javadoc for this is not very complete. Does anyone have a simple how-to for extending the auto-complete of a XML/HTML attribute ?

0

I extended HTML attribute completion using the CompletionData class:
1. Register the CompletionData instance in the ProjectComponent.initComponent() method:
CompletionUtil.registerCompletionData(getHtmlFileType(), new MyCompletionData());

2. The MyCompletionData class extends the HtmlCompletionData class and registers completion variant in the constructor:
LeftNeighbour left = new LeftNeighbour(new TextFilter("."));
CompletionVariant completionVariant = new CompletionVariant(new NotFilter(left));
completionVariant.includeScopeClass(com.intellij.psi.impl.source.tree.LeafPsiElement.class, true);
completionVariant.addCompletionFilterOnElement(TrueFilter.INSTANCE);
completionVariant.addCompletion(new AttributeValueVariantGetter(), 0);
completionVariant.setInsertHandler(new DefaultInsertHandler());
registerVariant(completionVariant);

0

Thanks for your help.

Everything is working fine now except for a small thing. I lost the "src" attribute auto-completion. With the default html attribute completion i get to browse files when i use auto-complete on the "src" attribute value of the "img" tag for example.
Now i get nothing. I still get auto-completion for all other attributes values, AFAIK.

Any ideas ?

0

Please sign in to leave a comment.