1
1
package cc.unitmesh.devti.gui.snippet
2
2
3
3
import cc.unitmesh.devti.util.parser.CodeFence
4
- import com.intellij.ide.scratch.ScratchRootType
5
4
import com.intellij.json.JsonLanguage
6
5
import com.intellij.json.psi.JsonFile
7
6
import com.intellij.json.psi.JsonLiteral
@@ -20,7 +19,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager
20
19
import com.intellij.openapi.project.DumbAwareAction
21
20
import com.intellij.openapi.project.Project
22
21
import com.intellij.openapi.util.Key
23
- import com.intellij.openapi.vfs.VirtualFile
22
+ import com.intellij.openapi.util.NlsSafe
24
23
import com.intellij.psi.PsiFile
25
24
import com.intellij.psi.PsiManager
26
25
import com.intellij.testFramework.LightVirtualFile
@@ -59,7 +58,8 @@ class AutoDevLanguageLabelAction : DumbAwareAction(), CustomComponentAction {
59
58
60
59
val project = e.project ? : return
61
60
if (lightVirtualFile.language == JsonLanguage .INSTANCE ) {
62
- lightVirtualFile = updateForDevContainer(project, lightVirtualFile) ? : lightVirtualFile
61
+ val content = editor.document.text
62
+ lightVirtualFile = updateForDevContainer(project, lightVirtualFile, content) ? : lightVirtualFile
63
63
}
64
64
65
65
val displayName =
@@ -69,33 +69,51 @@ class AutoDevLanguageLabelAction : DumbAwareAction(), CustomComponentAction {
69
69
70
70
private fun updateForDevContainer (
71
71
project : Project ,
72
- lightVirtualFile : LightVirtualFile
72
+ lightVirtualFile : LightVirtualFile ,
73
+ content : String
73
74
): LightVirtualFile ? {
75
+ // 判断文件名是否已经是 devcontainer 相关
76
+ val fileName = lightVirtualFile.name.lowercase()
77
+ if ((! content.startsWith(" {" ) && ! content.endsWith(" }" ))) return null
78
+
79
+ if (fileName == " devcontainer.json" || fileName.contains(" devcontainer" )) {
80
+ return lightVirtualFile
81
+ }
82
+
74
83
val psiFile = runReadAction { PsiManager .getInstance(project).findFile(lightVirtualFile) } ? : return null
75
- val image = getEnvObject( " image " , psiFile) ? : return null
84
+ val rootObject = ( psiFile as ? JsonFile )?.topLevelValue as ? JsonObject ? : return null
76
85
77
- val literal = image as ? JsonStringLiteral ? : return null
78
- val imageValue = literal.value
86
+ val hasDevContainerProps = rootObject.propertyList.any {
87
+ val propName = it.name
88
+ propName == " image" || propName == " dockerFile" || propName == " containerEnv" ||
89
+ propName == " remoteUser" || propName == " customizations" || propName == " features"
90
+ }
91
+
92
+ if (! hasDevContainerProps) return null
79
93
80
- if (! imageValue.contains(" mcr.microsoft.com/devcontainers" )) return null
94
+ val image = getEnvObject(" image" , psiFile) as ? JsonStringLiteral
95
+ val dockerfile = getEnvObject(" dockerFile" , psiFile) as ? JsonStringLiteral
96
+ val remoteUser = getEnvObject(" remoteUser" , psiFile) as ? JsonStringLiteral
97
+
98
+ val isDevContainer = when {
99
+ image != null && image.value.contains(" mcr.microsoft.com/devcontainers" ) -> true
100
+ dockerfile != null -> true
101
+ remoteUser != null -> true
102
+ rootObject.propertyList.size >= 3 && hasDevContainerProps -> true
103
+ else -> false
104
+ }
81
105
82
- // / create new file with name devcontainer.json
83
- val content = lightVirtualFile.inputStream.readBytes().toString(Charsets .UTF_8 )
84
- val newFile = LightVirtualFile (
85
- " devcontainer.json" ,
86
- JsonLanguage .INSTANCE ,
87
- content
88
- )
106
+ if (! isDevContainer) return null
107
+ val newFile = LightVirtualFile (" devcontainer.json" , JsonLanguage .INSTANCE , content)
89
108
90
109
try {
91
110
// follow: https://containers.dev/guide/dockerfile
92
111
// check image, exist, {
93
112
// "image": "mcr.microsoft.com/devcontainers/base:ubuntu"
94
113
95
114
val providers = JsonSchemaProviderFactory .EP_NAME .extensions.map { it.getProviders(project) }.flatten()
96
- .filter { it.isAvailable(lightVirtualFile ) }
115
+ .filter { it.isAvailable(newFile ) }
97
116
98
- // devcontainer.json
99
117
providers.map {
100
118
it.name
101
119
}
0 commit comments