Skip to content

Commit 3a37baa

Browse files
committed
feat(devin-lang): add support for DevInRunConfigurationProfileState and related changes #101
This commit introduces a new class `DevInRunConfigurationProfileState` which serves as the run profile state for the `AutoDevConfiguration`. It creates a `BuildProcessHandler` and attaches a `TerminalExecutionConsole` to it, providing a console view for the execution process. Additionally, the `DevInRunFileAction` has been modified to notify the user when a DevIn file will be run, and the `AutoDevConfiguration` now returns a `DevInRunConfigurationProfileState` instance for its state. The `DevInRunLineMarkersProvider` has been updated to implement the `DumbAware` interface, allowing it to work even if the project is in a dumb state.
1 parent ac187cf commit 3a37baa

File tree

4 files changed

+94
-2
lines changed

4 files changed

+94
-2
lines changed

exts/devin-lang/src/main/kotlin/cc/unitmesh/devti/language/actions/DevInRunFileAction.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package cc.unitmesh.devti.language.actions
22

3+
import cc.unitmesh.devti.AutoDevNotifications
34
import cc.unitmesh.devti.language.psi.DevInFile
45
import cc.unitmesh.devti.language.run.AutoDevConfiguration
56
import cc.unitmesh.devti.language.run.AutoDevConfigurationType
@@ -56,6 +57,7 @@ class DevInRunFileAction : DumbAwareAction() {
5657
ExecutionManager.getInstance(project).restartRunProfile(builder.build())
5758
}
5859

60+
AutoDevNotifications.notify(project, "Will Running DevIn file: ${file.name}")
5961
}
6062

6163
companion object {

exts/devin-lang/src/main/kotlin/cc/unitmesh/devti/language/run/AutoDevConfiguration.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class AutoDevConfiguration(project: Project, name: String, factory: AutoDevConfi
1717
override fun getIcon(): Icon = AutoDevIcons.AI_COPILOT
1818

1919
override fun getState(executor: Executor, environment: ExecutionEnvironment): RunProfileState? {
20-
return null
20+
return DevInRunConfigurationProfileState(project, this)
2121
}
2222

2323
override fun clone(): RunConfiguration {
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package cc.unitmesh.devti.language.run
2+
3+
import com.intellij.build.process.BuildProcessHandler
4+
import com.intellij.execution.DefaultExecutionResult
5+
import com.intellij.execution.ExecutionException
6+
import com.intellij.execution.ExecutionResult
7+
import com.intellij.execution.Executor
8+
import com.intellij.execution.configurations.RunProfileState
9+
import com.intellij.execution.process.ProcessHandler
10+
import com.intellij.execution.process.ProcessTerminatedListener
11+
import com.intellij.execution.runners.ProgramRunner
12+
import com.intellij.execution.ui.ConsoleView
13+
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTask
14+
import com.intellij.openapi.project.Project
15+
import com.intellij.openapi.util.io.StreamUtil
16+
import com.intellij.terminal.TerminalExecutionConsole
17+
import java.io.BufferedInputStream
18+
import java.io.BufferedOutputStream
19+
import java.io.InputStream
20+
import java.io.OutputStream
21+
import java.nio.channels.Channels
22+
import java.nio.channels.Pipe
23+
24+
class DevInRunConfigurationProfileState(
25+
private val myProject: Project,
26+
private val configuration: AutoDevConfiguration,
27+
) : RunProfileState {
28+
override fun execute(executor: Executor?, runner: ProgramRunner<*>): ExecutionResult {
29+
val processHandler: ProcessHandler = createProcessHandler(configuration.name)
30+
ProcessTerminatedListener.attach(processHandler)
31+
32+
val console: ConsoleView = TerminalExecutionConsole(myProject, processHandler)
33+
console.attachToProcess(processHandler)
34+
35+
return DefaultExecutionResult(console, processHandler)
36+
}
37+
38+
@Throws(ExecutionException::class)
39+
private fun createProcessHandler(myExecutionName: String): ProcessHandler {
40+
return object : BuildProcessHandler() {
41+
var myProcessInputWriter: OutputStream? = null
42+
var myProcessInputReader: InputStream? = null
43+
44+
init {
45+
val pipe = Pipe.open()
46+
47+
myProcessInputWriter = BufferedOutputStream(Channels.newOutputStream(pipe.sink()))
48+
myProcessInputReader = BufferedInputStream(Channels.newInputStream(pipe.source()))
49+
}
50+
51+
override fun detachIsDefault(): Boolean = false
52+
53+
override fun destroyProcessImpl() {
54+
try {
55+
// cancel myTask
56+
// myTask?.cancel()
57+
} finally {
58+
closeInput()
59+
}
60+
}
61+
62+
override fun detachProcessImpl() {
63+
try {
64+
notifyProcessDetached()
65+
} finally {
66+
closeInput()
67+
}
68+
}
69+
70+
override fun getProcessInput(): OutputStream? {
71+
return myProcessInputWriter
72+
}
73+
74+
override fun getExecutionName(): String {
75+
return myExecutionName
76+
}
77+
78+
protected fun closeInput() {
79+
val processInputWriter = myProcessInputWriter
80+
val processInputReader = myProcessInputReader
81+
myProcessInputWriter = null
82+
myProcessInputReader = null
83+
84+
StreamUtil.closeStream(processInputWriter)
85+
StreamUtil.closeStream(processInputReader)
86+
}
87+
}
88+
}
89+
}

exts/devin-lang/src/main/kotlin/cc/unitmesh/devti/language/run/DevInRunLineMarkersProvider.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ import com.intellij.execution.lineMarker.RunLineMarkerContributor
88
import com.intellij.icons.AllIcons
99
import com.intellij.openapi.actionSystem.ActionManager
1010
import com.intellij.openapi.actionSystem.AnAction
11+
import com.intellij.openapi.project.DumbAware
1112
import com.intellij.openapi.util.text.StringUtil
1213
import com.intellij.psi.PsiElement
1314
import com.intellij.util.containers.ContainerUtil
1415

15-
class DevInRunLineMarkersProvider : RunLineMarkerContributor() {
16+
class DevInRunLineMarkersProvider : RunLineMarkerContributor(), DumbAware {
1617
override fun getInfo(element: PsiElement): Info? {
1718
if (element.language !is DevInLanguage || element.textRange.startOffset != 0) return null
1819

0 commit comments

Comments
 (0)