How to apply a LineMarkerProviderDescriptor to a kotlin file outside of synced project modules?
Our plugin has a custom LineMarkerProviderDescriptor implementation for kotlin files, and it works nicely for us.
My problem is that this descriptor only seems to work for kotlin files that are synced in our project. We use a “focus” type approach to our project where only a small subset of our thousands of modules are synced by the IDE at a time (to improve performance). This means that if someone is browsing kt files in unloaded modules they can't benefit from the gutter icons we would like to be able to show, without needing to load the whole module.
I have noticed that other file types, such as xml and yml, still have file analysis performed in this case, but kt files seem to disable all analysis. Is there a way I can get my LineMarkerProviderDescriptor to run on kt files any time they are open in the editor, even if not in a synced project?
Please sign in to leave a comment.
Hi Eli,
Could you please share your implementation and your registration and plugin.xml?
Sure, I'll share it below.
Is there something you're looking for specifically with the implementation that might be wrong? I have used the debugger to validate that the
getLineMarkerInfo
function is never called in my implementation for kt files outside of a synced module, but it is called for synced kt files and works correctly there. We have another implementation for yaml files (registered in plugin.xml withlanguage="yaml"
) and I have verified that that implementation is always invoked for yaml files, even if they are not in synced modules.The plugin.xml contains this for the registration:
<extensions defaultExtensionNs="com.intellij">
<codeInsight.lineMarkerProvider
language="kotlin"
implementationClass="actions.trio.TrioLineMarkersProvider"/>
</extensions>
And the implementation looks something like this:
class TrioLineMarkersProvider : LineMarkerProviderDescriptor() {
override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo<*>? {
if (element !is KtClass || !(element.isTrioDeclaration() || element.isTrioUIClass())) {
return null
}
val identifier = element.nameIdentifier ?: return null
val filePath = element.containingFile.virtualFile.path
val module = getContainingModule(File(filePath)) ?: return null
val trioFqn = element.fqName?.toString() ?: return null
val generatedTestItems = getGeneratedTestItems(module, element, trioFqn)
return LineMarkerInfo(
identifier,
identifier.textRange,
ICON,
{ TITLE },
{ event, _ ->
showPopupOptions(
RelativePoint(event),
generatedTestItems,
module.gradleFullModuleName,
element.project,
)
},
GutterIconRenderer.Alignment.LEFT,
{ TITLE },
)
}
override fun getName(): String = TITLE
override fun getIcon(): Icon = ICON
}
Hello. Indeed, Kotlin files are not highlighted if outside the project source roots, because they require project structure knowledge (dependent modules, set up sdks, etc) to be highlightable. XML files, on the other hand, are frequently stashed all other the place and can be meaningfully highlighted even outside project structure.
To enable line marker highlighting, please de-unload the module which contains Kotlin files in question.
Thanks for the response. I need a way to surface custom information in a kotlin file _without_ having it loaded. Is there any other mechanism from Intellij that I could use? The only one that I can think of is a banner, which is not ideal.
So you want to highlight a Kotlin file from the unloaded module?
The inspections/annotators/line markers are disabled for these files. The only possibility I can think of is to register your own HighlightVisitor. The downside is that this api is too low-level and easy to get wrong.
Yes, that ‘s what I’d like to do. From reading just the file psi information and kotlin annotations we have enough information to surface the annotators we want to show - the project structure and other information is not necessary for our use case at all. Thank you for the information