How can I not block the ui or at least show a cancelable progress indicator for a long-ish task in a quick fix invocation?
Answered
I have this invoke method in an implementation of LocalQuickFixAndIntentionActionOnPsiElement
override fun invoke(project: Project, file: PsiFile, editor: Editor?, startElement: PsiElement, endElement: PsiElement) {
if (editor == null) return
val (panel, popup, constraints) = getPanelAndPopupAndConstraints()
panel.add(createLabel("Loading..."), constraints)
val point = editor.offsetToXY(startElement.textOffset)
point.translate(-editor.scrollingModel.horizontalScrollOffset, -editor.scrollingModel.verticalScrollOffset)
popup.show(editor.component, point.x, point.y)
object : SwingWorker<PsiDocComment?, Unit>() {
override fun doInBackground(): PsiDocComment? {
return ReadAction.compute<PsiDocComment?, Exception> {
val prompt = when (startElement) {
is PsiMethod -> getMethodPrompt(startElement, file)
is PsiClass -> getClassPrompt(startElement, file)
else -> return@compute null
}
return@compute getDocComment(project, prompt)
}
}
override fun done() {
popup.isVisible = false
val result = try { get() } catch (e: Exception) { null } ?: return
ApplicationManager.getApplication().invokeAndWait {
WriteCommandAction.runWriteCommandAction(project) {
val anchorBefore = startElement.children.firstOrNull { it !is PsiDocComment }
if (anchorBefore != null) {
startElement.addBefore(result, anchorBefore)
} else {
startElement.add(result)
}
}
}
}
}.execute()
}
I know this isn't really the right way of doing something like this, but for the life of me I cannot figure out from the docs how to do it correctly. I want to either not block the ui while the docComment is being generated (it's prompting an azure gpt model to do so), or I want to display a cancelable modal indicating clearly that the docs are being generated.
The process usually takes like 3 seconds, but sometimes on large classes it can take like 25.
Can anyone help me? Thanks.
Please sign in to leave a comment.
Okay I figured out a better way to do this, but it uses a deprecated method
runProcessWithProgressAsynchronously(Project, String, Runnable, Runnable, Runnable, PerformInBackgroundOption)
. Not sure how to convert it to use the non-deprecated one, though I did try.Any help with using the non-deprecated version?
Hi,
Did you try to implement
com.intellij.openapi.progress.ProgressManager#run(com.intellij.openapi.progress.Task)
? You should call it with a task extendingcom.intellij.openapi.progress.Task.Backgroundable
.If you tried, what was the problem?
I tried so many things in so many iterations that I honestly cannot remember.
Just tried it though, ended up with this, and it works great! Thank you.