Execute a piece of code when the run button/option is clicked

Answered

Hi!

For a research project I am working on, I need to take a "snapshot" of the code opened in the editor and send it to a server for analysis every time the user (student) runs the code.

I was already able to create a plugin that adds a new run button to the user interface that performs the action that I need and then "runs" the code and shows the result to the user.

The problem is that due to usability issues I have to execute the same action but using the default "run" button.

I have already developed a similar plugin for Eclipse, and in Eclipse you can add a dependency to org.eclipse.debug.core and then you can use
DebugPlugin.getDefault().getLaunchManager().addLaunchListener(
....

//
public void run(){
// the code that you want to execute every time the "run" button is pressed.
}
....

)

I was looking for something like this... is it possible? How? :)

Best regards,

Nuno.

0
4 comments

You may subscribe to `ExecutionManager.EXECUTION_TOPIC`.

0

Hi, Roman!

Thank you for the reply!

Unfortunately, I am very fresh concerning plugin development for the IDEA platform... :( So, here are some additional questions:

I have already developed a plugin that works well, but the user needs to press a custom button. So my plugin extends the AnAction class, and my code is executed inside the actionPerformed(AnActionEvent e) method.

To achieve what I want, my plugin can still extend the AnAction class? Could you please point me an example. I've already searched, but I am unable to find one.

If it helps, the code for my plugin is basically this:

_______________________________________________

public class CodeInsights extends AnAction {

public CodeInsights() {
super();
}

public void actionPerformed(AnActionEvent e) {

final Project project = e.getProject();
if (project == null) {
return;
}
Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
if (editor == null) {
return;
}
final Document document = editor.getDocument();
if (document == null) {
return;
}

StatusBar statusBar = WindowManager.getInstance()
.getStatusBar(project);

final RunManager runManager = RunManager.getInstance(project);
ChooseRunConfigurationPopup chooseRunConfigurationPopup = new ChooseRunConfigurationPopup(project, "ABC", DefaultRunExecutor.getRunExecutorInstance(), null );
chooseRunConfigurationPopup.show();

ProgramRunnerUtil.executeConfiguration(project, runManager.getSelectedConfiguration(), DefaultRunExecutor.getRunExecutorInstance());

try{
String url = "...";

URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();

//add request header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "CodeSnapshot/0.1");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

String urlParameters = "code=" + URLEncoder.encode(document.getText(), "UTF-8");

// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();

int responseCode = con.getResponseCode();

if (responseCode == 200){
// ...
} else{ // not 200
statusBar.setInfo("CI :: Error!");
}
} catch(Exception eio){
statusBar.setInfo("CI :: Error!");
}
}
}

_______________________________________________

Best regards,

Nuno.

 

0

Hi Nuno,

I got an impression that you didn't like the solution with a custom "Run" button, and want to be notified when a student runs his code via standard IDEA actions. Correct?

If yes, you will need something like this (assuming students run Java code):

import com.intellij.execution.ExecutionListener;
import com.intellij.execution.ExecutionManager;
import com.intellij.execution.application.ApplicationConfiguration;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import org.jetbrains.annotations.NotNull;

public class CodeInsights extends AbstractProjectComponent {
public CodeInsights(@NotNull Project project) {
super(project);
project.getMessageBus().connect().subscribe(ExecutionManager.EXECUTION_TOPIC, new ExecutionListener() {
@Override
public void processStarted(@NotNull String executorId, @NotNull ExecutionEnvironment env, @NotNull ProcessHandler handler) {
RunProfile profile = env.getRunProfile();
if (profile instanceof ApplicationConfiguration) {
PsiClass mainClass = ((ApplicationConfiguration)profile).getMainClass();
if (mainClass != null) {
sendText(mainClass.getContainingFile().getText());
}
}
}
});
}

private void sendText(String text) {
//...
}
}
<project-components>
  <component>
<implementation-class>...CodeInsights</implementation-class>
<loadForDefaultProject>false</loadForDefaultProject>
</component>
</project-components>

 

0

Hi Roman, 

Thank you so much! That was exactly what I was looking for. I have already modified and tested the plugin in PyCharm (my target IDE) and it is working very well. :)

I you ever come to Portugal I will be more than glad to offer you a beer (or whatever you drink!) .

Best regards,

Nuno.

0

Please sign in to leave a comment.