From 2e1988438b68c3edf6627e28ebf56004dacf9dc2 Mon Sep 17 00:00:00 2001 From: Andrew Charneski Date: Mon, 25 Sep 2023 11:55:29 -0400 Subject: [PATCH] 1.2.15 (#95) --- build.gradle.kts | 4 +- .../actions/code/CustomEditAction.groovy | 5 +- .../actions/generic/AnalogueFileAction.groovy | 3 +- .../aicoder/config/ActionSettingsRegistry.kt | 2 +- .../simiacryptus/aicoder/config/MRUItems.kt | 8 +- .../simiacryptus/aicoder/util/UITools.kt | 101 +++++++++++++++--- src/main/resources/META-INF/plugin.xml | 4 +- .../actions/code/CustomEditAction.groovy | 5 +- .../actions/generic/AnalogueFileAction.groovy | 3 +- 9 files changed, 109 insertions(+), 26 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 0fa444f5..c05d0ed1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -25,10 +25,10 @@ repositories { val kotlin_version = "1.7.22" val jetty_version = "11.0.15" val slf4j_version = "2.0.5" -val skyenet_version = "1.0.14" +val skyenet_version = "1.0.16" dependencies { - implementation(group = "com.simiacryptus", name = "joe-penai", version = "1.0.16") + implementation(group = "com.simiacryptus", name = "joe-penai", version = "1.0.18") implementation(group = "com.simiacryptus.skyenet", name = "util", version = skyenet_version) implementation(group = "com.simiacryptus.skyenet", name = "core", version = skyenet_version) diff --git a/src/main/groovy/com/github/simiacryptus/aicoder/actions/code/CustomEditAction.groovy b/src/main/groovy/com/github/simiacryptus/aicoder/actions/code/CustomEditAction.groovy index f6dcebe0..db7118c7 100644 --- a/src/main/groovy/com/github/simiacryptus/aicoder/actions/code/CustomEditAction.groovy +++ b/src/main/groovy/com/github/simiacryptus/aicoder/actions/code/CustomEditAction.groovy @@ -2,6 +2,7 @@ package com.github.simiacryptus.aicoder.actions.code import com.github.simiacryptus.aicoder.actions.SelectionAction import com.github.simiacryptus.aicoder.config.AppSettingsState +import com.github.simiacryptus.aicoder.util.UITools import com.intellij.openapi.project.Project import com.simiacryptus.openai.proxy.ChatProxy import org.jetbrains.annotations.Nullable @@ -60,7 +61,9 @@ class CustomEditAction extends SelectionAction { @Override String getConfig(@Nullable Project project) { - return JOptionPane.showInputDialog(null, "Instruction:", "Edit Code", JOptionPane.QUESTION_MESSAGE) + return UITools.showInputDialog(null, "Instruction:", "Edit Code", JOptionPane.QUESTION_MESSAGE + //, AppSettingsState.instance.getRecentCommands("customEdits").mostRecentHistory + ) } diff --git a/src/main/groovy/com/github/simiacryptus/aicoder/actions/generic/AnalogueFileAction.groovy b/src/main/groovy/com/github/simiacryptus/aicoder/actions/generic/AnalogueFileAction.groovy index 00f260ab..6ca3629c 100644 --- a/src/main/groovy/com/github/simiacryptus/aicoder/actions/generic/AnalogueFileAction.groovy +++ b/src/main/groovy/com/github/simiacryptus/aicoder/actions/generic/AnalogueFileAction.groovy @@ -53,7 +53,7 @@ class AnalogueFileAction extends FileContextAction @Override File[] processSelection(SelectionState state, Settings config) { - ProjectFile analogue = generateFile( + ProjectFile analogue = generateFile( new ProjectFile( path: state.projectRoot.toPath().relativize(state.selectedFile.toPath()), code: IOUtils.toString(new FileInputStream(state.selectedFile), "UTF-8") @@ -73,6 +73,7 @@ class AnalogueFileAction extends FileContextAction FileUtils.write(outputPath.toFile(), analogue.code, "UTF-8") Thread.sleep(100) return [outputPath.toFile()] + } private ProjectFile generateFile(ProjectFile baseFile, String directive) { diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/config/ActionSettingsRegistry.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/config/ActionSettingsRegistry.kt index d0686f6c..e4f5aa78 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/config/ActionSettingsRegistry.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/config/ActionSettingsRegistry.kt @@ -11,7 +11,7 @@ import java.util.stream.Collectors class ActionSettingsRegistry { val actionSettings: MutableMap = HashMap() - val version = 1.6 + val version = 1.8 fun edit(superChildren: Array): Array { val children = superChildren.toList().toMutableList() diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/config/MRUItems.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/config/MRUItems.kt index a9d05d8d..08860608 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/config/MRUItems.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/config/MRUItems.kt @@ -12,6 +12,9 @@ class MRUItems { var historyLimit = 10 fun addInstructionToHistory(instruction: CharSequence) { synchronized(mostRecentHistory) { + if(mostRecentHistory.contains(instruction.toString())) { + mostRecentHistory.remove(instruction.toString()) + } mostRecentHistory.add(instruction.toString()) while (mostRecentHistory.size > historyLimit) { mostRecentHistory.removeAt(0) @@ -35,9 +38,8 @@ class MRUItems { toRemove.removeAll(retain.toSet()) toRemove.removeAll(mostRecentHistory.toSet()) toRemove.forEach { key: CharSequence? -> - mostUsedHistory.remove( - key - ) + mostUsedHistory.remove(key) + mostRecentHistory.remove(key.toString()) } } } diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/util/UITools.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/util/UITools.kt index cd91fb28..e63ee1fa 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/util/UITools.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/util/UITools.kt @@ -51,6 +51,7 @@ import java.lang.reflect.Modifier import java.net.URI import java.util.* import java.util.concurrent.* +import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicReference import java.util.function.Supplier import java.util.stream.Collectors @@ -788,12 +789,6 @@ object UITools { return null } - @JvmStatic - fun isInterruptedException(e: Throwable?): Boolean { - if (e is InterruptedException) return true - return if (e!!.cause != null && e.cause !== e) isInterruptedException(e.cause) else false - } - @JvmStatic fun writeableFn( event: AnActionEvent, @@ -807,7 +802,10 @@ object UITools { class ModalTask( project : Project, title : String, canBeCancelled : Boolean, val task : (ProgressIndicator) -> T ) : Task.WithResult(project, title, canBeCancelled), Supplier { - private var result: T? = null + private val result = AtomicReference() + private val isError = AtomicBoolean(false) + private val error = AtomicReference() + private val semaphore = Semaphore(0) override fun compute(indicator: ProgressIndicator): T? { val currentThread = Thread.currentThread() val threads = ArrayList() @@ -818,19 +816,27 @@ object UITools { }, 0, 1, TimeUnit.SECONDS) threads.add(currentThread) return try { - result = task(indicator) - result!! + result.set(task(indicator)) + result.get() } catch (e: Throwable) { error(log, "Error running task", e) + isError.set(true) + error.set(e) null } finally { + semaphore.release() threads.remove(currentThread) scheduledFuture.cancel(true) } } override fun get(): T { - return result!! + semaphore.acquire() + semaphore.release() + if (isError.get()) { + throw error.get() + } + return result.get() } } @@ -839,7 +845,9 @@ object UITools { project : Project, title : String, canBeCancelled : Boolean, val task : (ProgressIndicator) -> T ) : Task.Backgroundable(project, title ?: "", canBeCancelled, DEAF), Supplier { - private val ref = AtomicReference() + private val result = AtomicReference() + private val isError = AtomicBoolean(false) + private val error = AtomicReference() private val semaphore = Semaphore(0) override fun run(indicator: ProgressIndicator) { val currentThread = Thread.currentThread() @@ -852,11 +860,13 @@ object UITools { threads.add(currentThread) try { val result = task(indicator) - ref.set(result) - semaphore.release() + this.result.set(result) } catch (e: Throwable) { error(log, "Error running task", e) + error.set(e) + isError.set(true) } finally { + semaphore.release() threads.remove(currentThread) scheduledFuture.cancel(true) } @@ -864,7 +874,11 @@ object UITools { override fun get(): T { semaphore.acquire() - return ref.get() + semaphore.release() + if (isError.get()) { + throw error.get() + } + return result.get() } } @@ -1196,6 +1210,65 @@ object UITools { return sw.toString() } + // Wrap JOptionPane.showInputDialog + @JvmStatic fun showInputDialog( + parentComponent: Component?, + message: Any?, + title: String?, + messageType: Int + ): Any? { + val icon = null + val selectionValues = null + val initialSelectionValue = null + val pane = JOptionPane( + message, + messageType, + JOptionPane.OK_CANCEL_OPTION, + icon, + null, + null + ) + pane.wantsInput = true + pane.selectionValues = selectionValues + pane.initialSelectionValue = initialSelectionValue + //pane.isComponentOrientationLeftToRight = true + val dialog = pane.createDialog(parentComponent, title) + pane.selectInitialValue() + dialog.show() + dialog.dispose() + val value = pane.inputValue + return if (value == JOptionPane.UNINITIALIZED_VALUE) null else value + } + +@JvmStatic fun showInputDialog( + parentComponent: Component?, + message: Any?, + title: String?, + messageType: Int, + mru: List, + providedOptions: List? +): Any? { + val icon = null + val selectionValues = (mru + (providedOptions ?: emptyList())).toTypedArray() + val initialSelectionValue = null + val pane = JOptionPane( + message, + messageType, + JOptionPane.OK_CANCEL_OPTION, + icon, + null, + null + ) + pane.wantsInput = true + pane.selectionValues = selectionValues + pane.initialSelectionValue = initialSelectionValue + val dialog = pane.createDialog(parentComponent, title) + pane.selectInitialValue() + dialog.show() + dialog.dispose() + val value = pane.inputValue + return if (value == JOptionPane.UNINITIALIZED_VALUE) null else value +} } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 91373a07..7920fb73 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -35,7 +35,7 @@ text="_AI Coder" icon="AllIcons.Actions.Lightning" description="AI coding assistant tools"> - + - + { @Override String getConfig(@Nullable Project project) { - return JOptionPane.showInputDialog(null, "Instruction:", "Edit Code", JOptionPane.QUESTION_MESSAGE) + return UITools.showInputDialog(null, "Instruction:", "Edit Code", JOptionPane.QUESTION_MESSAGE + //, AppSettingsState.instance.getRecentCommands("customEdits").mostRecentHistory + ) } diff --git a/src/main/resources/sources/groovy/com/github/simiacryptus/aicoder/actions/generic/AnalogueFileAction.groovy b/src/main/resources/sources/groovy/com/github/simiacryptus/aicoder/actions/generic/AnalogueFileAction.groovy index 00f260ab..6ca3629c 100644 --- a/src/main/resources/sources/groovy/com/github/simiacryptus/aicoder/actions/generic/AnalogueFileAction.groovy +++ b/src/main/resources/sources/groovy/com/github/simiacryptus/aicoder/actions/generic/AnalogueFileAction.groovy @@ -53,7 +53,7 @@ class AnalogueFileAction extends FileContextAction @Override File[] processSelection(SelectionState state, Settings config) { - ProjectFile analogue = generateFile( + ProjectFile analogue = generateFile( new ProjectFile( path: state.projectRoot.toPath().relativize(state.selectedFile.toPath()), code: IOUtils.toString(new FileInputStream(state.selectedFile), "UTF-8") @@ -73,6 +73,7 @@ class AnalogueFileAction extends FileContextAction FileUtils.write(outputPath.toFile(), analogue.code, "UTF-8") Thread.sleep(100) return [outputPath.toFile()] + } private ProjectFile generateFile(ProjectFile baseFile, String directive) {