Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
acharneski committed Feb 25, 2024
2 parents 222a476 + 5fc7c86 commit 57a0a16
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 50 deletions.
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ val skyenet_version = "1.0.47"
val remoterobot_version = "0.11.21"
dependencies {

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")

implementation(group = "com.simiacryptus.skyenet", name = "kotlin", version = skyenet_version)
{
exclude(group = "org.jetbrains.kotlin", module = "")
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pluginName=intellij-aicoder
pluginRepositoryUrl=https://github.com/SimiaCryptus/intellij-aicoder
pluginVersion=1.2.25
pluginVersion=1.2.26

jvmArgs=-Xmx8g
org.gradle.jvmargs=-Xmx8g
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,43 @@ import org.slf4j.LoggerFactory
import javax.swing.Icon

abstract class BaseAction(
name: String? = null,
description: String? = null,
icon: Icon? = null,
name: String? = null,
description: String? = null,
icon: Icon? = null,
) : AnAction(name, description, icon) {

private val log by lazy { LoggerFactory.getLogger(javaClass) }
//override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
private val log by lazy { LoggerFactory.getLogger(javaClass) }
//override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT

val api: OpenAIClient
get() = IdeaOpenAIClient.instance
val api: OpenAIClient
get() = IdeaOpenAIClient.instance

final override fun update(event: AnActionEvent) {
event.presentation.isEnabledAndVisible = isEnabled(event)
super.update(event)
}
final override fun update(event: AnActionEvent) {
event.presentation.isEnabledAndVisible = isEnabled(event)
super.update(event)
}

abstract fun handle(e: AnActionEvent)
abstract fun handle(e: AnActionEvent)


final override fun actionPerformed(e: AnActionEvent) {
UITools.logAction("""
final override fun actionPerformed(e: AnActionEvent) {
UITools.logAction(
"""
|Action: ${javaClass.simpleName}
""".trimMargin().trim())
IdeaOpenAIClient.lastEvent = e
try {
handle(e)
} catch (e: Throwable) {
UITools.error(log, "Error in Action ${javaClass.simpleName}", e)
}
""".trimMargin().trim()
)
IdeaOpenAIClient.lastEvent = e
try {
handle(e)
} catch (e: Throwable) {
UITools.error(log, "Error in Action ${javaClass.simpleName}", e)
}
}

open fun isEnabled(event: AnActionEvent): Boolean = true

open fun isEnabled(event: AnActionEvent): Boolean = true
companion object {
val log by lazy { LoggerFactory.getLogger(javaClass) }
val scheduledPool = java.util.concurrent.Executors.newScheduledThreadPool(1)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ package com.github.simiacryptus.aicoder.actions
import com.github.simiacryptus.aicoder.config.AppSettingsState
import com.github.simiacryptus.aicoder.util.UITools
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import org.slf4j.LoggerFactory
import java.io.File
import java.nio.file.Path
import java.util.concurrent.TimeUnit

abstract class FileContextAction<T : Any>(
private val supportsFiles: Boolean = true,
Expand Down Expand Up @@ -42,18 +45,16 @@ abstract class FileContextAction<T : Any>(
if (it.isCanceled) throw InterruptedException()
}
UITools.writeableFn(e) {
val files = newFiles.map { file ->
val files = newFiles.mapNotNull { file ->
val localFileSystem = LocalFileSystem.getInstance()
localFileSystem.findFileByIoFile(file.parentFile)?.refresh(false, true)
val generatedFile = localFileSystem.findFileByIoFile(file)
if (generatedFile == null) {
log.warn("Generated file not found: ${file.path}")
} else {
generatedFile.refresh(false, false)
FileEditorManager.getInstance(project).openFile(generatedFile, true)
open(project, file.toPath())
}
generatedFile
}.filter { it != null }.toTypedArray<VirtualFile?>()
}.toTypedArray<VirtualFile?>()
Runnable {
files.forEach { it?.delete(this@FileContextAction) }
}
Expand All @@ -78,6 +79,33 @@ abstract class FileContextAction<T : Any>(

companion object {
private val log = LoggerFactory.getLogger(FileContextAction::class.java)

fun open(project: Project, outputPath: Path) {
lateinit var function: () -> Unit
function = {
val file = outputPath.toFile()
if (file.exists()) {
// Ensure the IDE is ready for file operations
ApplicationManager.getApplication().invokeLater {
val ioFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file)
if (false == (ioFile?.let { FileEditorManager.getInstance(project).isFileOpen(it) })) {
val localFileSystem = LocalFileSystem.getInstance()
// Refresh the file system to ensure the file is visible
val virtualFile = localFileSystem.refreshAndFindFileByIoFile(file)
virtualFile?.let {
FileEditorManager.getInstance(project).openFile(it, true)
} ?: scheduledPool.schedule(function, 100, TimeUnit.MILLISECONDS)
} else {
scheduledPool.schedule(function, 100, TimeUnit.MILLISECONDS)
}
}
} else {
scheduledPool.schedule(function, 100, TimeUnit.MILLISECONDS)
}
}
scheduledPool.schedule(function, 100, TimeUnit.MILLISECONDS)
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import com.github.simiacryptus.aicoder.actions.FileContextAction
import com.github.simiacryptus.aicoder.config.AppSettingsState
import com.github.simiacryptus.aicoder.config.Name
import com.github.simiacryptus.aicoder.util.UITools
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.LocalFileSystem
import com.simiacryptus.jopenai.ApiModel
import com.simiacryptus.jopenai.ApiModel.ChatMessage
import com.simiacryptus.jopenai.ApiModel.Role
Expand All @@ -14,6 +17,8 @@ import org.apache.commons.io.FileUtils
import org.apache.commons.io.IOUtils
import java.io.File
import java.io.FileInputStream
import java.nio.file.Path
import java.util.concurrent.TimeUnit
import javax.swing.JTextArea

class AnalogueFileAction : FileContextAction<AnalogueFileAction.Settings>() {
Expand All @@ -38,39 +43,48 @@ class AnalogueFileAction : FileContextAction<AnalogueFileAction.Settings>() {
)
}

class Settings (
var directive: String = ""
class UserSettings(
var directive: String = "",
)

override fun getConfig(project: Project?): Settings? {
return UITools.showDialog(
project,
SettingsUI::class.java,
Settings::class.java,
"Create Analogue File"
class Settings(
val settings: UserSettings? = null,
val project: Project? = null
)

override fun getConfig(project: Project?): Settings {
return Settings(
UITools.showDialog(
project,
SettingsUI::class.java,
UserSettings::class.java,
"Create Analogue File"
), project
)
}

override fun processSelection(state: SelectionState, config: Settings?): Array<File> {
val root = getModuleRootForFile(state.selectedFile).toPath()
val selectedFile = state.selectedFile
val analogue = generateFile(
ProjectFile(
path = state.projectRoot.toPath().relativize(state.selectedFile.toPath()).toString(),
code = IOUtils.toString(FileInputStream(state.selectedFile), "UTF-8")
path = root.relativize(selectedFile.toPath()).toString(),
code = IOUtils.toString(FileInputStream(selectedFile), "UTF-8")
),
config?.directive ?: ""
config?.settings?.directive ?: ""
)
var outputPath = state.projectRoot.toPath().resolve(analogue.path)
var outputPath = root.resolve(analogue.path)
if (outputPath.toFile().exists()) {
val extension = outputPath.toString().split(".").last()
val name = outputPath.toString().split(".").dropLast(1).joinToString(".")
val fileIndex = (1..Int.MAX_VALUE).find {
!File(state.projectRoot, "$name.$it.$extension").exists()
!root.resolve("$name.$it.$extension").toFile().exists()
}
outputPath = state.projectRoot.toPath().resolve("$name.$fileIndex.$extension")
outputPath = root.resolve("$name.$fileIndex.$extension")
}
outputPath.parent.toFile().mkdirs()
FileUtils.write(outputPath.toFile(), analogue.code, "UTF-8")
Thread.sleep(100)
open(config?.project!!, outputPath)
return arrayOf(outputPath.toFile())
}

Expand Down Expand Up @@ -103,10 +117,7 @@ class AnalogueFileAction : FileContextAction<AnalogueFileAction.Settings>() {

)
)
val response = api.chat(
chatRequest,
AppSettingsState.instance.defaultChatModel()
).choices.first().message?.content?.trim()
val response = api.chat(chatRequest, model).choices.first().message?.content?.trim()
var outputPath = baseFile.path
val header = response?.split("\n")?.first()
var body = response?.split("\n")?.drop(1)?.joinToString("\n")?.trim()
Expand All @@ -123,4 +134,43 @@ class AnalogueFileAction : FileContextAction<AnalogueFileAction.Settings>() {
code = body ?: ""
)
}

companion object {
fun open(project: Project, outputPath: Path) {
lateinit var function: () -> Unit
function = {
val file = outputPath.toFile()
if (file.exists()) {
// Ensure the IDE is ready for file operations
ApplicationManager.getApplication().invokeLater {
val ioFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file)
if (false == (ioFile?.let { FileEditorManager.getInstance(project).isFileOpen(it) })) {
val localFileSystem = LocalFileSystem.getInstance()
// Refresh the file system to ensure the file is visible
val virtualFile = localFileSystem.refreshAndFindFileByIoFile(file)
virtualFile?.let {
FileEditorManager.getInstance(project).openFile(it, true)
} ?: scheduledPool.schedule(function, 100, TimeUnit.MILLISECONDS)
} else {
scheduledPool.schedule(function, 100, TimeUnit.MILLISECONDS)
}
}
} else {
scheduledPool.schedule(function, 100, TimeUnit.MILLISECONDS)
}
}
scheduledPool.schedule(function, 100, TimeUnit.MILLISECONDS)
}

fun getModuleRootForFile(file: File): File {
var current = file
while (current.parentFile != null) {
if (current.resolve(".git").exists()) {
return current
}
current = current.parentFile
}
return file
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import java.util.stream.Collectors
class ActionSettingsRegistry {

val actionSettings: MutableMap<String, ActionSettings> = HashMap()
private val version = 2.0027
private val version = 2.0040

fun edit(superChildren: Array<out AnAction>): Array<AnAction> {
val children = superChildren.toList().toMutableList()
Expand Down
13 changes: 11 additions & 2 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
text="_Chat Append Text"
description="Append text using the Chat API">
<!--DOC
The `Chat Append Text` action allows you to quickly append text to the end of the current selection.
The `Chat Append Text` action allows you to quickly append text to the end of the current selection.
-->
<add-to-group group-id="com.github.simiacryptus.aicoder.ui.EditorMenu" anchor="first"/>
<keyboard-shortcut keymap="$default" first-keystroke="shift control Q" second-keystroke="A"/>
Expand All @@ -91,7 +91,7 @@
text="_Create File"
description="Create file">
<!--DOC
The `Create File` action allows you to quickly create a new file via a user-supplied directive.
The `Create File` action allows you to quickly create a new file via a user-supplied directive.
-->
<add-to-group group-id="com.github.simiacryptus.aicoder.ui.ProjectMenu" anchor="first"/>
</action>
Expand All @@ -105,6 +105,15 @@
-->
<add-to-group group-id="com.github.simiacryptus.aicoder.ui.ProjectMenu" anchor="first"/>
</action>
<action class="com.github.simiacryptus.aicoder.actions.generic.DocumentationCompilerAction"
text="Compile Documentation"
description="Compile documentation">
<!--DOC
The `Compile Documentation` action allows you to quickly compile the documentation for the current project.
This is useful for quickly generating documentation for your project.
-->
<add-to-group group-id="com.github.simiacryptus.aicoder.ui.ProjectMenu" anchor="first"/>
</action>
<action class="com.github.simiacryptus.aicoder.actions.generic.RedoLast"
text="Re_do Last"
description="Redo last">
Expand Down

0 comments on commit 57a0a16

Please sign in to comment.