8. Line Marker Provider
线标记有助于使用装订线上的图标注释任何代码.
这些图标可以提供相关代码的导航.
8.1.
定义线标记提供程序
让我们在Java代码中注释我们的属性的用法,并提供对这些属性的定义的导航.
package com.simpleplugin;
import com.intellij.codeInsight.daemon.*;
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.simpleplugin.psi.SimpleProperty;
import org.jetbrains.annotations.NotNull;
import java.util.*;
public class SimpleLineMarkerProvider extends RelatedItemLineMarkerProvider {
@Override
protected void collectNavigationMarkers(@NotNull PsiElement element,
Collection<? super RelatedItemLineMarkerInfo> result) {
if (element instanceof PsiLiteralExpression) {
PsiLiteralExpression literalExpression = (PsiLiteralExpression) element;
String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null;
if (value != null && value.startsWith("simple" + ":")) {
Project project = element.getProject();
final List<SimpleProperty> properties = SimpleUtil.findProperties(project, value.substring(7));
if (properties.size() > 0) {
NavigationGutterIconBuilder<PsiElement> builder =
NavigationGutterIconBuilder.create(SimpleIcons.FILE).
setTargets(properties).
setTooltipText("Navigate to a simple property");
result.add(builder.createLineMarkerInfo(element));
}
}
}
}
}
实施者的更多技术细节
*请返回行标记信息以获取您要求的确切元素.
例如,如果为方法调用了getLineMarkerInfo()
,则不返回类标记信息.
*请尽可能小的元素返回相关的行标记信息.
例如,不要为[PsiMethod
]返回方法标记(upsource:///java/java-psi-api/src/com/intellij/psi/PsiMethod.java).
而是将其返回给PsiIdentifier
,这是此方法的名称.
更多技术细节:
当LineMarkerProvider
为太大的PsiElement返回一些东西时会发生什么?
public class MyLineMarkerProvider implements LineMarkerProvider {
public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
if (element instanceof PsiMethod) return new LineMarkerInfo(element, ...);
return null;
}
}
检查(特别是LineMarkersPass
)出于性能原因查询所有LineMarkerProviders
两次通过:
*首次通过可见区域中的所有元素
*所有其余元素的第二遍
如果提供者不为任何区域返回任何内容,则会清除其线标记.
如果是,例如 一个方法是半可见的(它的名字是可见的,但它的一部分不是)和
一些写得不好的LineMarkerProvider
返回了’PsiMethod而不是'PsiIdentifier
的信息,然后:
*第一遍删除行标记信息,因为整个’PsiMethod`不可见.
*第二遍试图添加行标记信息,因为最后为PsiMethod
调用了’LineMarkerProvider`.
结果,线标记图标会恼人地闪烁.
要解决此问题,请重写LineMarkerProvider
以返回’PsiIdentifier而不是'PsiMethod
的信息:
public class MyLineMarkerProvider implements LineMarkerProvider {
public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
if (element instanceof PsiIdentifier && element.getParent() instanceof PsiMethod) return new LineMarkerInfo(element, ...);
return null;
}
}
8.2.
注册行标记提供程序
<codeInsight.lineMarkerProvider language="JAVA" implementationClass="com.simpleplugin.SimpleLineMarkerProvider"/>
8.3.
运行该项目
现在,您可以在装订线上看到图标,并可以导航到属性定义.