IDEA Plugin 开发:自动添加 getter 和 setter 注释折叠区域
要实现在 IDEA 中自动为连续的 getter 和 setter 方法添加注释折叠区域,并自动折叠,可以使用 IDEA 的 PSI(Program Structure Interface)来分析和修改代码。
首先,创建一个实现 FileEditorManagerListener 接口的类,例如 MyFileEditorManagerListener:
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.FoldingModelEx;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class MyFileEditorManagerListener implements FileEditorManagerListener {
@Override
public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
Project project = source.getProject();
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
if (psiFile instanceof PsiJavaFile) {
PsiJavaFile javaFile = (PsiJavaFile) psiFile;
javaFile.addPsiTreeChangeListener(new PsiTreeChangeAdapter() {
@Override
public void childAdded(@NotNull PsiTreeChangeEvent event) {
PsiElement child = event.getChild();
if (child instanceof PsiMethod) {
PsiMethod psiMethod = (PsiMethod) child;
if (psiMethod.isConstructor() || psiMethod.getNameIdentifier() == null || !psiMethod.getNameIdentifier().getText().startsWith('get')) {
return;
}
PsiElement parent = psiMethod.getParent();
if (!(parent instanceof PsiClass)) {
return;
}
PsiClass psiClass = (PsiClass) parent;
PsiMethod[] methods = psiClass.getMethods();
List<PsiMethod> getterSetters = new ArrayList<>();
for (PsiMethod method : methods) {
if (isGetterSetter(method)) {
getterSetters.add(method);
} else if (!getterSetters.isEmpty()) {
addFoldingRegion(project, javaFile, getterSetters);
getterSetters.clear();
}
}
if (!getterSetters.isEmpty()) {
addFoldingRegion(project, javaFile, getterSetters);
}
}
}
});
}
}
private boolean isGetterSetter(PsiMethod method) {
String methodName = method.getName();
if (methodName.startsWith('get') || methodName.startsWith('set')) {
PsiParameterList parameterList = method.getParameterList();
return parameterList.getParametersCount() == 0;
}
return false;
}
private void addFoldingRegion(Project project, PsiJavaFile javaFile, List<PsiMethod> getterSetters) {
PsiElementFactory factory = PsiElementFactory.getInstance(project);
PsiElement firstMethod = getterSetters.get(0);
PsiElement lastMethod = getterSetters.get(getterSetters.size() - 1);
PsiComment startComment = factory.createCommentFromText('//region Getter and Setter Methods', null);
PsiComment endComment = factory.createCommentFromText('//endregion', null);
TextRange range = new TextRange(firstMethod.getTextOffset(), lastMethod.getTextOffset() + lastMethod.getTextLength());
javaFile.addBefore(startComment, firstMethod);
javaFile.addAfter(endComment, lastMethod);
Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
if (editor instanceof EditorEx) {
FoldingModelEx foldingModel = ((EditorEx) editor).getFoldingModel();
foldingModel.addFoldRegion(range.getStartOffset(), range.getEndOffset(), 'Getter and Setter Methods');
}
}
}
然后,在你的插件的 plugin.xml 文件中注册 FileEditorManagerListener:
<idea-plugin>
...
<extensions defaultExtensionNs="com.intellij">
...
<fileEditorManagerListener implementation="com.example.MyFileEditorManagerListener"/>
</extensions>
</idea-plugin>
这样,当打开一个 Java 文件时,插件会自动为连续的 getter 和 setter 方法添加注释折叠区域,并自动折叠。
原文地址: https://www.cveoy.top/t/topic/qhFS 著作权归作者所有。请勿转载和采集!