要实现在 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 方法添加注释折叠区域,并自动折叠。

IDEA Plugin 开发:自动添加 getter 和 setter 注释折叠区域

原文地址: https://www.cveoy.top/t/topic/qhFS 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录