NavigationGutterIconRenderer goes to file/offset of element instead of invoking element's navigate()
The NavigationGutterIconRenderer uses PsiNavigateUtil.navigate() method which uses the element’s virtual file and offset rather than the Navigatable of the element when available:
public class PsiNavigateUtil {
public static void navigate(@Nullable final PsiElement psiElement) {
if (psiElement != null && psiElement.isValid()) {
final PsiElement navigationElement = psiElement.getNavigationElement();
final int offset = navigationElement instanceof PsiFile ? -1 : navigationElement.getTextOffset();
VirtualFile virtualFile = PsiUtilCore.getVirtualFile(psiElement);
if (virtualFile != null && virtualFile.isValid()) {
new OpenFileDescriptor(navigationElement.getProject(), virtualFile, offset).navigate(true);
}
else if (navigationElement instanceof Navigatable) {
((Navigatable)navigationElement).navigate(true);
}
}
}
}
I am passing a list of PsiElement to NavigationGutterIconBuilder and the element in this case is a FakePsiElement subclass with customized navigate() method.
To make it work, I am returning null from the FakePsiElement.getContainingFile() method which causes the above code to invoke the navigate() method. I am not sure if this will have undesired effect under some conditions.
What is the right way to customize the navigate action for line marker to prevent the action from navigating to the virtual file of the element?
Please sign in to leave a comment.
Thanks for reporting! There doesn't seem to be an easy way to customize the navigation action, but it appears that NavigationGutterIconRenderer could call "navigate". I can change that in master, but it'll need some testing time before it can be backported to release branches.
Thanks Peter. I could not find an easy way of customizing the navigate action and thought I missed something.
Changing the code to call
navigate()if available and otherwise go to element offset in the file will only affect the next release version and can lead to side-effects. I would still need to support the functionality in previous releases. In other words, I would not recommend you do this on my account.I am fine with returning a null for getContainingFile() and both
Goto Declarationand line marker navigation work. I was just wondering if there was less of a kludged solution.I would probably prefer for future versions to have an easier way maybe by allowing to pass a custom
NavigationGutterIconRendererinstead of the hardcoded privateMyNavigationGutterIconRendererimplementation.It doesn't seem to be very easy to add customization where NavigationGutterIconRenderer is returned. It'd probably require to introduce a protected method with 6 parameters which doesn't smell well.
Actually, all this NavigationGutterIconBuilder API is very DOM-related, with a lot of support for indirection and laziness. If you don't need all this, I'd recommend you to consider extending GutterIconRenderer directly: you might end up with less code, which is easier to understand and modify.
Yes, it seems like an easier and better option. I will try it.