How to make a request few seconds after the user stop typing and update source code?

Hey guys,

We're creating a plug-in that gets code suggestion from a micro service (API) based on user request (like Github copilot, but for an specific niche of application).

If the user types:

# read excel file sorting by date descending

The plug-in injects a code snippet for that purpose.

It's working, we are using TypedHandlerDelegate to monitor the file and make the request and update the code.

But our plug-in is making a request at each typed key. It would be better to wait the user to stop typing the key after a few milliseconds or making requests in some intervals.

What we would like to do:

- use a thread to avoid making lot of requests (make a request after a few keys typed or after some time).

Is there a way to keep a thread running in the background that is able to write (add snippet) into the source code file?
Is there a way to schedule a thread (write privileges) to run after some time? (2 seconds after a key/event happened)
Any suggestion of a better approach?
1
1 comment

Hi there, I implements a similiar delay trigger function in my Notes plugin(https://plugins.jetbrains.com/plugin/17501-notes), the code is just simple and easy to use, and here I grant the rights for you to use this code in any projects:

package com.github.beansoft.task;

import beansoft.intellij.util.ui.GuiUtilsEx;
import beansoft.util.HtmlStringUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.ui.GuiUtils;
import com.intellij.util.ui.UIUtil;

import java.util.Timer;
import java.util.TimerTask;


public class WriteSafeDebounceTask {
private Timer timer;
private Long delay;
private Runnable runnable;

public WriteSafeDebounceTask(Runnable runnable, Long delay) {
this.runnable = runnable;
this.delay = delay;
}

/**
*
* @param runnable
* @param delay delay in milliseconds before task is to be executed.
* @return
*/
public static WriteSafeDebounceTask build(Runnable runnable, Long delay){
return new WriteSafeDebounceTask(runnable, delay);
}


public void run(){
if(timer!=null){
timer.cancel();
}
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
timer=null;

if(ApplicationManager.getApplication() == null) {
UIUtil.invokeLaterIfNeeded(runnable);
// runnable.run();
} else {
GuiUtilsEx.invokeLaterIfNeeded(
runnable, ModalityState.defaultModalityState()

);
}

}
}, delay);
}

public static void main(String[] args) {
WriteSafeDebounceTask task = WriteSafeDebounceTask.build(()
-> System.out.println("do task: "+ HtmlStringUtil.nowTimestamp()),1000L);
long delay = 100;

int i = 0;
while (true){
System.out.println("call task: "+ HtmlStringUtil.nowTimestamp());
task.run();
i++;
if(i == 20) {
break;
}
// delay+=100;
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

public class GuiUtilsEx {

public static void invokeLaterIfNeeded(@NotNull Runnable runnable, @NotNull ModalityState modalityState) {
Application app = ApplicationManager.getApplication();
if (app.isDispatchThread()) {
runnable.run();
}
else {
app.invokeLater(runnable, modalityState);
}
}


}
1

Please sign in to leave a comment.