@@ -4,6 +4,15 @@ import mu.KotlinLogging
4
4
import com.intellij.lang.Language
5
5
import com.intellij.openapi.actionSystem.AnActionEvent
6
6
import com.intellij.openapi.actionSystem.CommonDataKeys
7
+ import com.intellij.openapi.actionSystem.PlatformDataKeys
8
+ import com.intellij.openapi.project.Project
9
+ import com.intellij.openapi.vfs.VirtualFile
10
+ import com.intellij.psi.PsiDirectory
11
+ import com.intellij.psi.PsiElement
12
+ import com.intellij.psi.PsiFile
13
+ import com.intellij.psi.PsiFileSystemItem
14
+ import org.jetbrains.kotlin.idea.core.util.toPsiDirectory
15
+ import org.jetbrains.kotlin.idea.core.util.toPsiFile
7
16
8
17
private val logger = KotlinLogging .logger {}
9
18
@@ -16,15 +25,71 @@ abstract class LanguageAssistant {
16
25
private val languages = mutableMapOf<String , LanguageAssistant >()
17
26
18
27
fun get (e : AnActionEvent ): LanguageAssistant ? {
19
- e.getData(CommonDataKeys .PSI_FILE )?.language?.let { language ->
20
- if (! languages.containsKey(language.id)) {
21
- loadWithException(language)?.let {
22
- languages.put(language.id, it.kotlin.objectInstance as LanguageAssistant )
28
+ val project = e.project ? : return null
29
+ val editor = e.getData(CommonDataKeys .EDITOR )
30
+ if (editor != null ) {
31
+ // The action is being called from editor
32
+ e.getData(CommonDataKeys .PSI_FILE )?.language?.let { language ->
33
+ updateLanguages(language)
34
+ return languages[language.id]
35
+ } ? : return null
36
+ } else {
37
+ // The action is being called from 'Project' tool window
38
+ val language = when (val element = e.getData(CommonDataKeys .PSI_ELEMENT )) {
39
+ is PsiFileSystemItem -> {
40
+ e.getData(CommonDataKeys .VIRTUAL_FILE_ARRAY )?.let {
41
+ findLanguageRecursively(project, it)
42
+ }
23
43
}
24
- }
44
+ is PsiElement -> {
45
+ element.containingFile?.let { getLanguageFromFile(it) }
46
+ }
47
+ else -> {
48
+ val someSelection = e.getData(PlatformDataKeys .SELECTED_ITEMS )? : return null
49
+ someSelection.firstNotNullOfOrNull {
50
+ when (it) {
51
+ is PsiFileSystemItem -> findLanguageRecursively(project, arrayOf(it.virtualFile))
52
+ is PsiElement -> it.language
53
+ else -> { null }
54
+ }
55
+ }
56
+ }
57
+ } ? : return null
58
+
59
+ updateLanguages(language)
25
60
return languages[language.id]
26
61
}
27
- return null
62
+ }
63
+
64
+ private fun updateLanguages (language : Language ) {
65
+ if (! languages.containsKey(language.id)) {
66
+ loadWithException(language)?.let {
67
+ languages.put(language.id, it.kotlin.objectInstance as LanguageAssistant )
68
+ }
69
+ }
70
+ }
71
+
72
+ private fun getLanguageFromFile (file : PsiFile ): Language ? {
73
+ updateLanguages(file.language)
74
+ return if (languages.containsKey(file.language.id))
75
+ file.language
76
+ else
77
+ null
78
+ }
79
+
80
+ private fun findLanguageRecursively (directory : PsiDirectory ): Language ? {
81
+ return directory.files
82
+ .firstNotNullOfOrNull { getLanguageFromFile(it) } ? :
83
+ directory.subdirectories.firstNotNullOfOrNull { findLanguageRecursively(it) }
84
+ }
85
+
86
+ private fun findLanguageRecursively (project : Project , virtualFiles : Array <VirtualFile >): Language ? {
87
+ val psiFiles = virtualFiles.mapNotNull { it.toPsiFile(project) }
88
+ val psiDirectories = virtualFiles.mapNotNull { it.toPsiDirectory(project) }
89
+
90
+
91
+ val fileLanguage = psiFiles.firstNotNullOfOrNull { getLanguageFromFile(it) }
92
+ return fileLanguage ? : psiDirectories.firstNotNullOfOrNull { findLanguageRecursively(it) }
28
93
}
29
94
}
30
95
}
0 commit comments