Skip to content

Commit c17158f

Browse files
committed
feat(prompts): replace executeOnPooledThread with coroutines and ModalityState in prompt dialog
This enables switching to EDT when setting prompt preview.
1 parent baed926 commit c17158f

File tree

3 files changed

+29
-21
lines changed

3 files changed

+29
-21
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
### Changed
1111

1212
- Rethrow generic exceptions when generating commit messages.
13+
- Replace `executeOnPooledThread` with coroutines and `ModalityState`.
1314

1415
### Fixed
1516

src/main/kotlin/com/github/blarc/ai/commits/intellij/plugin/settings/AppSettingsConfigurable.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,17 @@ import com.intellij.ui.CommonActionsPanel
1414
import com.intellij.ui.ToolbarDecorator
1515
import com.intellij.ui.components.JBCheckBox
1616
import com.intellij.ui.dsl.builder.*
17+
import kotlinx.coroutines.CoroutineScope
1718
import java.util.*
1819

1920
// Most of the settings are global, but we use project configurable to set isProjectSpecificLLMClient property
20-
class AppSettingsConfigurable(val project: Project) : BoundConfigurable(message("settings.general.group.title")) {
21+
class AppSettingsConfigurable(val project: Project, cs: CoroutineScope) : BoundConfigurable(message("settings.general.group.title")) {
2122

2223
private val llmClientTable = LLMClientTable()
2324
private lateinit var llmClientConfigurationComboBox: ComboBox<LLMClientConfiguration>
2425
private var isProjectSpecificLLMClientCheckBox = JBCheckBox(message("settings.llmClient.projectSpecific"))
2526
private lateinit var llmClientToolbarDecorator: ToolbarDecorator
26-
private val promptTable = PromptTable()
27+
private val promptTable = PromptTable(cs)
2728
private lateinit var toolbarDecorator: ToolbarDecorator
2829
private lateinit var promptComboBox: ComboBox<Prompt>
2930

src/main/kotlin/com/github/blarc/ai/commits/intellij/plugin/settings/prompts/PromptTable.kt

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ import com.github.blarc.ai.commits.intellij.plugin.unique
1212
import com.intellij.dvcs.repo.VcsRepositoryManager
1313
import com.intellij.ide.DataManager
1414
import com.intellij.openapi.actionSystem.CommonDataKeys
15-
import com.intellij.openapi.application.ApplicationManager
15+
import com.intellij.openapi.application.EDT
1616
import com.intellij.openapi.application.ModalityState
17+
import com.intellij.openapi.application.asContextElement
1718
import com.intellij.openapi.project.Project
1819
import com.intellij.openapi.ui.DialogWrapper
1920
import com.intellij.ui.components.JBTextArea
@@ -25,12 +26,16 @@ import com.intellij.ui.dsl.builder.text
2526
import com.intellij.ui.table.TableView
2627
import com.intellij.util.ui.ListTableModel
2728
import git4idea.branch.GitBranchWorker
29+
import kotlinx.coroutines.CoroutineScope
30+
import kotlinx.coroutines.Dispatchers
31+
import kotlinx.coroutines.launch
32+
import kotlinx.coroutines.withContext
2833
import java.awt.event.MouseAdapter
2934
import java.awt.event.MouseEvent
3035
import javax.swing.ListSelectionModel.SINGLE_SELECTION
3136
import kotlin.math.max
3237

33-
class PromptTable {
38+
class PromptTable(private val cs: CoroutineScope) {
3439
private var prompts = AppSettings2.instance.prompts
3540
private val tableModel = createTableModel()
3641

@@ -59,7 +64,7 @@ class PromptTable {
5964
)
6065

6166
fun addPrompt(): Prompt? {
62-
val dialog = PromptDialog(prompts.keys.toSet())
67+
val dialog = PromptDialog(prompts.keys.toSet(), cs)
6368

6469
if (dialog.showAndGet()) {
6570
prompts = prompts.plus(dialog.prompt.name.lowercase() to dialog.prompt).toMutableMap()
@@ -78,7 +83,7 @@ class PromptTable {
7883

7984
fun editPrompt(): Pair<Prompt, Prompt>? {
8085
val selectedPrompt = table.selectedObject ?: return null
81-
val dialog = PromptDialog(prompts.keys.toSet(), selectedPrompt.copy())
86+
val dialog = PromptDialog(prompts.keys.toSet(), cs, selectedPrompt.copy())
8287

8388
if (dialog.showAndGet()) {
8489
prompts = prompts.minus(selectedPrompt.name.lowercase()).toMutableMap()
@@ -104,7 +109,7 @@ class PromptTable {
104109
AppSettings2.instance.prompts = prompts
105110
}
106111

107-
private class PromptDialog(val prompts: Set<String>, val newPrompt: Prompt? = null) : DialogWrapper(true) {
112+
private class PromptDialog(val prompts: Set<String>, private val cs: CoroutineScope, val newPrompt: Prompt? = null) : DialogWrapper(true) {
108113

109114
val prompt = newPrompt ?: Prompt("")
110115
val promptNameTextField = JBTextField()
@@ -141,25 +146,13 @@ class PromptTable {
141146

142147
DataManager.getInstance().getDataContext(rootPane).getData(CommonDataKeys.PROJECT)?.let { project ->
143148
this.project = project
144-
ApplicationManager.getApplication().executeOnPooledThread {
145-
146-
val changes = VcsRepositoryManager.getInstance(project).repositories.stream()
147-
.map { r -> GitBranchWorker.loadTotalDiff(r, r.currentBranchName!!) }
148-
.flatMap { r -> r.stream() }
149-
.toList()
150-
151-
branch = commonBranch(changes, project)
152-
diff = computeDiff(changes, true, project)
153-
154-
ApplicationManager.getApplication().invokeLater({
155-
setPreview(prompt.content, promptHintTextField.text)
156-
}, ModalityState.stateForComponent(rootPane))
157-
}
149+
getChangesAndSetPreview(project)
158150
}
159151

160152
init()
161153
}
162154

155+
163156
override fun createCenterPanel() = panel {
164157
row(message("settings.prompt.name")) {
165158
cell(promptNameTextField)
@@ -204,6 +197,19 @@ class PromptTable {
204197
}
205198
}
206199

200+
private fun getChangesAndSetPreview(project: Project) = cs.launch(Dispatchers.IO + ModalityState.stateForComponent(rootPane).asContextElement()) {
201+
val changes = VcsRepositoryManager.getInstance(project).repositories.stream()
202+
.map { r -> GitBranchWorker.loadTotalDiff(r, r.currentBranchName!!) }
203+
.flatMap { r -> r.stream() }
204+
.toList()
205+
206+
branch = commonBranch(changes, project)
207+
diff = computeDiff(changes, true, project)
208+
209+
withContext(Dispatchers.EDT) {
210+
setPreview(prompt.content, promptHintTextField.text)
211+
}
212+
}
207213
private fun setPreview(promptContent: String, hint: String) {
208214
val constructPrompt = AICommitsUtils.constructPrompt(promptContent, diff, branch, hint, project)
209215
promptPreviewTextArea.text = constructPrompt.substring(0, constructPrompt.length.coerceAtMost(10000))

0 commit comments

Comments
 (0)