Skip to content

Commit

Permalink
feat(prompts): replace executeOnPooledThread with coroutines and Moda…
Browse files Browse the repository at this point in the history
…lityState in prompt dialog

This enables switching to EDT when setting prompt preview.
  • Loading branch information
Blarc committed Sep 9, 2024
1 parent baed926 commit c17158f
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
### Changed

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

### Fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ import com.intellij.ui.CommonActionsPanel
import com.intellij.ui.ToolbarDecorator
import com.intellij.ui.components.JBCheckBox
import com.intellij.ui.dsl.builder.*
import kotlinx.coroutines.CoroutineScope
import java.util.*

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

private val llmClientTable = LLMClientTable()
private lateinit var llmClientConfigurationComboBox: ComboBox<LLMClientConfiguration>
private var isProjectSpecificLLMClientCheckBox = JBCheckBox(message("settings.llmClient.projectSpecific"))
private lateinit var llmClientToolbarDecorator: ToolbarDecorator
private val promptTable = PromptTable()
private val promptTable = PromptTable(cs)
private lateinit var toolbarDecorator: ToolbarDecorator
private lateinit var promptComboBox: ComboBox<Prompt>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import com.github.blarc.ai.commits.intellij.plugin.unique
import com.intellij.dvcs.repo.VcsRepositoryManager
import com.intellij.ide.DataManager
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.EDT
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.asContextElement
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.DialogWrapper
import com.intellij.ui.components.JBTextArea
Expand All @@ -25,12 +26,16 @@ import com.intellij.ui.dsl.builder.text
import com.intellij.ui.table.TableView
import com.intellij.util.ui.ListTableModel
import git4idea.branch.GitBranchWorker
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
import javax.swing.ListSelectionModel.SINGLE_SELECTION
import kotlin.math.max

class PromptTable {
class PromptTable(private val cs: CoroutineScope) {
private var prompts = AppSettings2.instance.prompts
private val tableModel = createTableModel()

Expand Down Expand Up @@ -59,7 +64,7 @@ class PromptTable {
)

fun addPrompt(): Prompt? {
val dialog = PromptDialog(prompts.keys.toSet())
val dialog = PromptDialog(prompts.keys.toSet(), cs)

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

fun editPrompt(): Pair<Prompt, Prompt>? {
val selectedPrompt = table.selectedObject ?: return null
val dialog = PromptDialog(prompts.keys.toSet(), selectedPrompt.copy())
val dialog = PromptDialog(prompts.keys.toSet(), cs, selectedPrompt.copy())

if (dialog.showAndGet()) {
prompts = prompts.minus(selectedPrompt.name.lowercase()).toMutableMap()
Expand All @@ -104,7 +109,7 @@ class PromptTable {
AppSettings2.instance.prompts = prompts
}

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

val prompt = newPrompt ?: Prompt("")
val promptNameTextField = JBTextField()
Expand Down Expand Up @@ -141,25 +146,13 @@ class PromptTable {

DataManager.getInstance().getDataContext(rootPane).getData(CommonDataKeys.PROJECT)?.let { project ->
this.project = project
ApplicationManager.getApplication().executeOnPooledThread {

val changes = VcsRepositoryManager.getInstance(project).repositories.stream()
.map { r -> GitBranchWorker.loadTotalDiff(r, r.currentBranchName!!) }
.flatMap { r -> r.stream() }
.toList()

branch = commonBranch(changes, project)
diff = computeDiff(changes, true, project)

ApplicationManager.getApplication().invokeLater({
setPreview(prompt.content, promptHintTextField.text)
}, ModalityState.stateForComponent(rootPane))
}
getChangesAndSetPreview(project)
}

init()
}


override fun createCenterPanel() = panel {
row(message("settings.prompt.name")) {
cell(promptNameTextField)
Expand Down Expand Up @@ -204,6 +197,19 @@ class PromptTable {
}
}

private fun getChangesAndSetPreview(project: Project) = cs.launch(Dispatchers.IO + ModalityState.stateForComponent(rootPane).asContextElement()) {
val changes = VcsRepositoryManager.getInstance(project).repositories.stream()
.map { r -> GitBranchWorker.loadTotalDiff(r, r.currentBranchName!!) }
.flatMap { r -> r.stream() }
.toList()

branch = commonBranch(changes, project)
diff = computeDiff(changes, true, project)

withContext(Dispatchers.EDT) {
setPreview(prompt.content, promptHintTextField.text)
}
}
private fun setPreview(promptContent: String, hint: String) {
val constructPrompt = AICommitsUtils.constructPrompt(promptContent, diff, branch, hint, project)
promptPreviewTextArea.text = constructPrompt.substring(0, constructPrompt.length.coerceAtMost(10000))
Expand Down

0 comments on commit c17158f

Please sign in to comment.