From f58ed8858a151bddbec2c002f5a77ebc7d7a748b Mon Sep 17 00:00:00 2001 From: Luo Tim Date: Wed, 3 Jul 2024 23:33:01 +0800 Subject: [PATCH 1/2] Use runInEdt instead of invokeLater in createNewFile handler --- src/main/kotlin/ai/devchat/core/handlers/NewSrcFile.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/ai/devchat/core/handlers/NewSrcFile.kt b/src/main/kotlin/ai/devchat/core/handlers/NewSrcFile.kt index f8719a9..df433ec 100644 --- a/src/main/kotlin/ai/devchat/core/handlers/NewSrcFile.kt +++ b/src/main/kotlin/ai/devchat/core/handlers/NewSrcFile.kt @@ -6,6 +6,7 @@ import ai.devchat.plugin.currentProject import com.alibaba.fastjson.JSONObject import com.intellij.lang.Language import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.runInEdt import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.psi.PsiFile import com.intellij.psi.PsiFileFactory @@ -20,9 +21,9 @@ class NewSrcFile(requestAction: String, metadata: JSONObject?, payload: JSONObje override fun action() { val content = payload!!.getString("content") val language = payload!!.getString("language") - ApplicationManager.getApplication().invokeLater { - val project = currentProject ?: return@invokeLater - val dir = FileEditorManager.getInstance(project).selectedEditor?.file?.parent ?: return@invokeLater + runInEdt { + val project = currentProject ?: return@runInEdt + val dir = FileEditorManager.getInstance(project).selectedEditor?.file?.parent ?: return@runInEdt ApplicationManager.getApplication().runWriteAction { val psiDirectory = PsiManager.getInstance(project).findDirectory(dir) ?: return@runWriteAction val (fileLanguage, ext) = getLanguageByName(language) ?: return@runWriteAction From 3f41c1b5dbb3f48fc4de5ba356e95524fbdb0fff Mon Sep 17 00:00:00 2001 From: Luo Tim Date: Wed, 3 Jul 2024 23:34:13 +0800 Subject: [PATCH 2/2] Create util to ensure method is running in EDT and applied --- .../kotlin/ai/devchat/plugin/IDEServer.kt | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/ai/devchat/plugin/IDEServer.kt b/src/main/kotlin/ai/devchat/plugin/IDEServer.kt index 24f0c71..b419179 100644 --- a/src/main/kotlin/ai/devchat/plugin/IDEServer.kt +++ b/src/main/kotlin/ai/devchat/plugin/IDEServer.kt @@ -48,6 +48,7 @@ import kotlinx.serialization.Serializable import java.awt.Point import java.io.File import java.net.ServerSocket +import java.util.concurrent.FutureTask import kotlin.reflect.full.memberFunctions @@ -365,21 +366,36 @@ fun getAvailablePort(startPort: Int): Int { } } -fun Project.getPsiFile(filePath: String): PsiFile = ReadAction.compute { - val virtualFile = LocalFileSystem.getInstance().findFileByIoFile(File(filePath)) - PsiManager.getInstance(this).findFile(virtualFile!!) +fun runInEdtAndGet(block: () -> T): T { + val app = ApplicationManager.getApplication() + return if (app.isDispatchThread) { block() } else { + val future = FutureTask(block) + app.invokeAndWait { future.run() } + future.get() + } +} + +fun Project.getPsiFile(filePath: String): PsiFile = runInEdtAndGet { + ReadAction.compute { + val virtualFile = LocalFileSystem.getInstance().findFileByIoFile(File(filePath)) + PsiManager.getInstance(this).findFile(virtualFile!!) + } } -fun Project.getDocument(filePath: String): Document = ReadAction.compute { - LocalFileSystem.getInstance().findFileByIoFile(File(filePath))?.let { - FileDocumentManager.getInstance().getDocument(it) +fun Project.getDocument(filePath: String): Document = runInEdtAndGet { + ReadAction.compute { + LocalFileSystem.getInstance().findFileByIoFile(File(filePath))?.let { + FileDocumentManager.getInstance().getDocument(it) + } } } -fun Project.getCurrentFile(): VirtualFile = ReadAction.compute { - val editor: Editor? = FileEditorManager.getInstance(this).selectedTextEditor - editor?.document?.let { document -> - FileDocumentManager.getInstance().getFile(document) +fun Project.getCurrentFile(): VirtualFile = runInEdtAndGet { + ReadAction.compute { + val editor: Editor? = FileEditorManager.getInstance(this).selectedTextEditor + editor?.document?.let { document -> + FileDocumentManager.getInstance().getFile(document) + } } }