Triggering Action based on Editor Events

已回答

Hi!

I would like to call the iterateContent() function everytime the user completes code statements in the editor.
With code statements i mean things like:

Variable declaration e.g private int test;
functions e.g private void doSomething(){}
and so on

Currently I'm calling iterateContent() evertyime ';' or '}' is typed in the editor but that's not really what I want. Is there a more efficient/convenient way to do this?

public class GetSourceCode extends AnAction {


static {
final TypedAction typedAction = TypedAction.getInstance();
typedAction.setupRawHandler(new TypedHandler(typedAction.getRawHandler()));
}

@Override
public void update(AnActionEvent e) {
// Using the event, evaluate the context, and enable or disable the action.
// Set the availability based on whether a project is open
Project project = e.getProject();
e.getPresentation().setEnabledAndVisible(project != null);
}

@Override
public void actionPerformed(@NotNull AnActionEvent e) {
// Using the event, implement an action. For example, create and show a dialog.
}
}

public class TypedHandler implements TypedActionHandler {

private TypedActionHandler myOriginalActionHandler;

public TypedHandler(TypedActionHandler originalHandler) {
myOriginalActionHandler = originalHandler;
}

@Override
public void execute(@NotNull Editor editor, char charTyped, @NotNull DataContext dataContext) {
myOriginalActionHandler.execute(editor, charTyped, dataContext);
if (charTyped == ';' || charTyped == '}') {
Project project = editor.getProject();
iterateContent(project);
}
}


private void iterateContent(Project project) {
//iterate through project files; check if instanceof PsiJavaFile; print out PsiClass.getText()
}
}
0

Onuryi,

Depending on the TypedHandler to track the code may be a bit risky. Have you considered listening to the PSI changes with PsiTreeChangeListener (also PsiTreeChangeAdapter)

You can register it with:

PsiManager.getInstance(myProject).addPsiTreeChangeListener(PsiTreeChangeListener);

 

0

Thanks Jakub!

I will have a look at it!

0

Jakub Chrzanowski

I tried using the PsiTreeChangeListener but somehow I get a weird output. My code looks like following:

public class CodeTracker implements PsiTreeChangeListener {


@Override
public void beforeChildAddition(@NotNull PsiTreeChangeEvent event) {

}

@Override
public void beforeChildRemoval(@NotNull PsiTreeChangeEvent event) {

}

@Override
public void beforeChildReplacement(@NotNull PsiTreeChangeEvent event) {

}

@Override
public void beforeChildMovement(@NotNull PsiTreeChangeEvent event) {

}

@Override
public void beforeChildrenChange(@NotNull PsiTreeChangeEvent event) {

}

@Override
public void beforePropertyChange(@NotNull PsiTreeChangeEvent event) {

}

@Override
public void childAdded(@NotNull PsiTreeChangeEvent event) {

if(event.getChild() instanceof PsiField || event.getChild() instanceof PsiMethod){
System.out.println("child added");
}
System.out.println(event.getChild().getText());


}

@Override
public void childRemoved(@NotNull PsiTreeChangeEvent event) {

if(event.getChild() instanceof PsiField || event.getChild() instanceof PsiMethod){
System.out.println("child removed");
}
}

@Override
public void childReplaced(@NotNull PsiTreeChangeEvent event) {

}

@Override
public void childrenChanged(@NotNull PsiTreeChangeEvent event) {

}

@Override
public void childMoved(@NotNull PsiTreeChangeEvent event) {

}

@Override
public void propertyChanged(@NotNull PsiTreeChangeEvent event) {

}
}

public class GetSourceCode extends AnAction {


static{
CodeTracker codeTracker = new CodeTracker();
Project project = getActiveProject();
PsiManager.getInstance(project).addPsiTreeChangeListener(codeTracker);
}

@Override
public void update(AnActionEvent e) {
// Using the event, evaluate the context, and enable or disable the action.
// Set the availability based on whether a project is open
Project project = e.getProject();
e.getPresentation().setEnabledAndVisible(project != null);
}

@Override
public void actionPerformed(@NotNull AnActionEvent e) {
// Using the event, implement an action. For example, create and show a dialog.
}

private static Project getActiveProject(){
Project[] projects = ProjectManager.getInstance().getOpenProjects();
Project activeProject = null;
for (Project project : projects) {
Window window = WindowManager.getInstance().suggestParentWindow(project);
if (window != null && window.isActive()) {
activeProject = project;
}
}
return activeProject;
}
}
When I run this code and enter for example private int test; in the editor I get the following output:

p




private

i

0

I gues my mistake is that I'm working with the PsiTreeChangeEvent instead of using ChachedValue and PsiModificationTracker. Are there any examples on how to use them together?

0

请先登录再写评论。