Skip to content

Commit e74019a

Browse files
committed
feat(devin-lang): add FileAutoCommand and refactor DevInCompiler to support dynamic file content retrieval. #101
This commit introduces a new class `FileAutoCommand` which is responsible for executing commands that involve dynamic file content. It handles the retrieval of file content from the specified path, and if a range is specified, it will only return the specified portion of the file. The `DevInCompiler` class has been refactored to use this new command, and a fallback text is now provided in case the file content cannot be retrieved. This commit also removes unnecessary imports and simplifies the codebase.
1 parent a3d25f6 commit e74019a

File tree

3 files changed

+71
-36
lines changed

3 files changed

+71
-36
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package cc.unitmesh.devti.language.compiler
2+
3+
interface AutoCommand {
4+
fun execute(): String?
5+
}

exts/devin-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/DevInCompiler.kt

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,8 @@ import cc.unitmesh.devti.language.psi.DevInUsed
77
import com.intellij.openapi.diagnostic.logger
88
import com.intellij.openapi.editor.Editor
99
import com.intellij.openapi.project.Project
10-
import com.intellij.openapi.project.guessProjectDir
11-
import com.intellij.openapi.roots.ProjectFileIndex
1210
import com.intellij.openapi.util.NlsSafe
13-
import com.intellij.openapi.util.TextRange
14-
import com.intellij.openapi.vfs.LocalFileSystem
15-
import com.intellij.openapi.vfs.VirtualFile
16-
import com.intellij.openapi.vfs.VirtualFileManager
17-
import com.intellij.psi.PsiManager
18-
import com.intellij.psi.search.FilenameIndex
1911
import com.intellij.psi.util.elementType
20-
import kotlin.io.path.readText
2112

2213
class DevInCompiler(val myProject: Project, val file: DevInFile, val editor: Editor? = null) {
2314
private val logger = logger<DevInCompiler>()
@@ -68,7 +59,7 @@ class DevInCompiler(val myProject: Project, val file: DevInFile, val editor: Edi
6859
return
6960
}
7061

71-
processingCommand(command, propElement!!.text)
62+
processingCommand(command, propElement!!.text, fallbackText = used.text)
7263
}
7364

7465
DevInTypes.AGENT_START -> {
@@ -90,34 +81,11 @@ class DevInCompiler(val myProject: Project, val file: DevInFile, val editor: Edi
9081
}
9182
}
9283

93-
private fun processingCommand(command: BuiltinCommand, prop: @NlsSafe String) {
84+
private fun processingCommand(command: BuiltinCommand, prop: String, fallbackText: String) {
9485
when (command) {
9586
BuiltinCommand.FILE -> {
96-
val range: TextRange? = if (prop.contains("#")) {
97-
val rangeStr = prop.substringAfter("#")
98-
val start = rangeStr.substringBefore("-").toInt()
99-
val end = rangeStr.substringAfter("-").toInt()
100-
TextRange(start, end)
101-
} else {
102-
null
103-
}
104-
105-
val filepath = prop.trim()
106-
val projectPath = myProject.guessProjectDir()?.toNioPath()
107-
val realpath = projectPath?.resolve(filepath)
108-
val content = realpath?.readText()
109-
110-
content?.let {
111-
val virtualFile: VirtualFile? = VirtualFileManager.getInstance().findFileByNioPath(realpath)
112-
val lang = virtualFile?.let {
113-
PsiManager.getInstance(myProject).findFile(it)?.language?.displayName
114-
} ?: ""
115-
116-
output.append("\n```$lang\n")
117-
output.append(content)
118-
output.append("\n```\n")
119-
}
120-
87+
val result = FileAutoCommand(myProject, prop).execute() ?: fallbackText
88+
output.append(result)
12189
}
12290

12391
BuiltinCommand.REV -> {
@@ -136,4 +104,5 @@ class DevInCompiler(val myProject: Project, val file: DevInFile, val editor: Edi
136104
}
137105
}
138106
}
107+
139108
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package cc.unitmesh.devti.language.compiler
2+
3+
import com.intellij.openapi.diagnostic.logger
4+
import com.intellij.openapi.project.Project
5+
import com.intellij.openapi.project.guessProjectDir
6+
import com.intellij.openapi.util.TextRange
7+
import com.intellij.openapi.vfs.VirtualFileManager
8+
import com.intellij.psi.PsiManager
9+
10+
class FileAutoCommand(val myProject: Project, val prop: String) : AutoCommand {
11+
private val logger = logger<FileAutoCommand>()
12+
private val output = StringBuilder()
13+
14+
override fun execute(): String? {
15+
val range: TextRange? = if (prop.contains("#")) {
16+
val rangeStr = prop.substringAfter("#")
17+
val start = rangeStr.substringBefore("-").toInt()
18+
val end = rangeStr.substringAfter("-").toInt()
19+
TextRange(start, end)
20+
} else {
21+
null
22+
}
23+
24+
val projectPath = myProject.guessProjectDir()?.toNioPath()
25+
val realpath = projectPath?.resolve(prop.trim())
26+
27+
val virtualFile =
28+
VirtualFileManager.getInstance().findFileByUrl("file://${realpath?.toAbsolutePath()}")
29+
30+
val contentsToByteArray = virtualFile?.contentsToByteArray()
31+
if (contentsToByteArray == null) {
32+
logger.warn("File not found: $realpath")
33+
return null
34+
}
35+
36+
contentsToByteArray.let {
37+
val lang = virtualFile.let {
38+
PsiManager.getInstance(myProject).findFile(it)?.language?.displayName
39+
} ?: ""
40+
41+
val content = it.toString(Charsets.UTF_8)
42+
val fileContent = if (range != null) {
43+
val subContent = try {
44+
content.substring(range.startOffset, range.endOffset)
45+
} catch (e: StringIndexOutOfBoundsException) {
46+
content
47+
}
48+
49+
subContent
50+
} else {
51+
content
52+
}
53+
54+
output.append("\n```$lang\n")
55+
output.append(fileContent)
56+
output.append("\n```\n")
57+
}
58+
59+
return output.toString()
60+
}
61+
}

0 commit comments

Comments
 (0)