I'm developing a IntelliJ IDEA plugin to get context at current caret. More specific, I need to get a list of variables' types and names that can be used at caret. For example:
public static void main(String[] args) throws IOException {
Workbook wb = new HSSFWorkbook();
// caret 1
Sheet sheet = wb.createSheet("new sheet");
Row row = sheet.createRow((short) 1);
for(int i = 0; i < 5; i++) {
// caret 2
row.createCell(i).setCellValue("X");
}
// caret 3
}
I need to get wb: Workbook
at caret 1, wb: Workbook, sheet: Sheet, row: Row, i: int
at caret 2 and wb: Workbook, sheet: Sheet, row: Row
at caret 3 because i: int
is no longer in the scope.
This link seems related, it suggests file.findElementAt(editor.getCaretModel().getOffset())
. This expression returns a PsiElement
object. However, when I get context of this object and traverse the context using PsiRecursiveElementVisitor
, it will visit elements defined after caret, which doesn't meet my requirement above.
My code:
public class ContextView extends AnAction {
public void actionPerformed(AnActionEvent event) {
final Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
final Project project = event.getRequiredData(CommonDataKeys.PROJECT);
//Access document, caret, and selection
final Document document = editor.getDocument();
PsiJavaFile javaFile = (PsiJavaFile) PsiDocumentManager.getInstance(project).getPsiFile(document);
PsiElement currentEle = javaFile.findElementAt(editor.getCaretModel().getOffset());
PsiElement cxt = currentEle.getContext();
cxt.accept(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
System.out.println(element.toString());
super.visitElement(element);
}
});
}
}
So how to solve the problem?
This link seems related, it suggests file.findElementAt(editor.getCaretModel().getOffset()). This expression returns a PsiElement object. However, when I get context of this object and traverse the context using PsiRecursiveElementVisitor, it will visit elements defined after caret, which doesn't meet my requirement above.
Have you tried com.intellij.psi.util.PsiTreeUtil#getParentOfType(com.intellij.psi.PsiElement, java.lang.Class<T>)
? You may fill the first argument with the result of findElementAt
, and the second argument with PsiDeclarationStatement.class
, which is the Psi class for variable declarations.
By this you can get the local variable declaration. You can test by sout(parent.getText())