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">
${header.text}
<div>

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
.firstOrNull()
}

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:

<caret>data-sly-use.header
d<caret>ata-sly-use.header
da<caret>ta-sly-use.header
dat<caret>a-sly-use.header
data<caret>-sly-use.header
data-<caret>sly-use.header
data-s<caret>ly-use.header

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

data-sl<caret>y-use.header

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

0

Please sign in to leave a comment.