PsiElement接口是文件中光标所在的那个字段,或者光标所在的那个方法的抽象,例如下图中,PsiElement就是private String name
IntelliJ Platform-Plugins-获取鼠标选中字段或方法(PsiElement抽象)-LMLPHP
而下图中PsiElement就是public String getName()
IntelliJ Platform-Plugins-获取鼠标选中字段或方法(PsiElement抽象)-LMLPHP

下面的代码会演示:光标在方法上,就打印方法名字,光标在字段上,就打印字段名字,但是我们在写代码之前还要做一些其他工作,由于IntelliJ平台的变化,导致不在默认加载PsiMethodImplPsiFieldImpl两个类所在的jar包,而我们恰好要用到这两个类,所以需要手动依赖这两个类,我们在plugin.xml增加如下依赖

// 下面这1行是项目创建的时候就自带的
<depends>com.intellij.modules.platform</depends>
// 下面这2行是我们刚刚添加的,我们需要的两个类就在下面的jar包下
<depends>com.intellij.modules.lang</depends>
<depends>com.intellij.modules.java</depends>

官网说明在这个地址
代码示例

import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.source.PsiFieldImpl;
import com.intellij.psi.impl.source.PsiMethodImpl;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.keyFMap.KeyFMap;
import org.jetbrains.annotations.NotNull;

public class MyAction extends AnAction {
	@Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        PsiElement psiElement = e.getData(PlatformDataKeys.PSI_ELEMENT);
        if (psiElement != null) {
            PsiManager manager = psiElement.getManager();
            IElementType elementType = psiElement.getNode().getElementType();
            // 如果光标所在位置是一个方法
            if ("METHOD".equals(elementType.toString())) {
                PsiMethodImpl m = (PsiMethodImpl) psiElement;
                System.out.println(m.getName());
            }
            // 如果光标所在位置是一个字段
            if ("FIELD".equals(elementType.toString())) {
                PsiFieldImpl f = (PsiFieldImpl) psiElement;
                System.out.println(f.getName());
            }
        }
    }
}

部分方法总结,前提示例代码如下:

public class UserEntity {

   /**
	* 怀念二抱
	* 想念三抱
	**/
    private String name;

    public String getName() {
        return name;
    }
}

获取name字段的偏移量(光标必须在name上)

PsiElement psiElement = e.getData(PlatformDataKeys.PSI_ELEMENT);
PsiFieldImpl f = (PsiFieldImpl) psiElement;
int offset = f.getTextOffset();

获取UserEntity的偏移量(实际得到的是字母U前面空格的偏移量,拿到结果自己+1即可)

PsiElement psiElement = e.getData(PlatformDataKeys.PSI_ELEMENT);
PsiFieldImpl f = (PsiFieldImpl) psiElement;
int offset = f.getStartOffsetInParent();

获取name字段注释(光标必须在name上),也就是本示例的"怀念二抱"和"想念三抱"

PsiElement psiElement = e.getData(PlatformDataKeys.PSI_ELEMENT);
PsiFieldImpl f = (PsiFieldImpl) psiElement;
PsiDocComment javaDoc = f.getDocComment();
for (PsiElement descriptionElement : descriptionElements) {
    // 因为是文本操作,所以我们只取我们写的注释,忽略斜杠星号什么的,所以此处if判断
    // 只有PsiDocToken的子类PsiDocTokenImpl才是我们写的注释,这个if会进入2次,
    // 1次是"怀念二抱"
    // 1次是"想念三抱"
    if(descriptionElement instanceof PsiDocToken){
        System.out.println(descriptionElement.getText());
    }
}
05-09 09:31