References highlighting in template language

I have a problem with references between HTML and custom template language (HTL - HTML Template Language).
HTL variable can be defined with special HTML attribute and used inside of HTL expression (inside of ${}). Example:

<div data-sly-use.header="com.example.Header">

In the example above we have variable "header".

My HtlVariable implements PsiNamedElement:

abstract class HtlVariableMixin(node: ASTNode) : ASTWrapperPsiElement(node), PsiNamedElement {

override fun getReference(): HtlVariableReference? {
val htlVariable = node.psi as? HtlVariable ?: return null
return HtlVariableReference(htlVariable)

override fun setName(name: String) = this

override fun getName(): String = text

I implemented PsiReference:

class HtlVariableReference(htlVariable: HtlVariable) : PsiReferenceBase<HtlVariable>(htlVariable) {

override fun resolve(): PsiElement? {
val htmlFile = element.containingFile.viewProvider.getPsi(StdLanguages.HTML)
val variableName = element.identifier.text
return blockVariableAttribute(htmlFile, variableName)

private fun blockVariableAttribute(htmlFile: PsiFile, variableName: String?): PsiElement? {
return HtlSearch.blockVariables(htmlFile)
.filter { it.identifier == variableName } // identifier is part after dot in "data-sly-use.<var>"
.map { it.definer } // definer's type is XmlAttribute

override fun getVariants() = emptyArray<Any>()

The resolve() method resolves to HTML attribute declaring variable, so in our example Ctrl + click on header in ${header.text} will resolve to data-sly-use.header="com.example.Header" attribute. When I place caret at "header" in ${header.text}, then attribute name is highlighted. When I place caret this ways:


it's still highlighted. But when I place it at this place:


it's not. It seems that it's highlighted only when caret is at attribute name in range of "header" length. The "header" length is 6, so attribute is highlighted only when caret is at 0-6 character.
Is there any way to make highlighting working even if caret position exceeds variable name length? Perfect solution would be to navigate only to variable name (to "header" in "data-sly-use.header") and highlight references only when caret is at "header" in attribute. But if it's not possible, then highlighting entire attribute name and references would be also sufficient.
If information I provided is not enough, please let me know.

1 comment

Hi Karol,

would you be so kind to share your diff against master and a sample project? That would help a lot with understanding of what's going on


Please sign in to leave a comment.