diff --git a/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/DevInsCompiler.kt b/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/DevInsCompiler.kt index ce85c8b6a7..673539e3c5 100644 --- a/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/DevInsCompiler.kt +++ b/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/DevInsCompiler.kt @@ -6,6 +6,7 @@ import cc.unitmesh.devti.language.parser.CodeBlockElement import cc.unitmesh.devti.language.psi.DevInFile import cc.unitmesh.devti.language.psi.DevInTypes import cc.unitmesh.devti.language.psi.DevInUsed +import cc.unitmesh.devti.provider.devins.DevInsSymbolProvider import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project @@ -114,7 +115,8 @@ class DevInsCompiler(private val myProject: Project, val file: DevInFile, val ed } BuiltinCommand.SYMBOL -> { - PrintInsCommand("/" + commandNode.commandName + ":" + prop) + result.isLocalCommand = true + SymbolInsCommand(myProject, prop) } BuiltinCommand.WRITE -> { @@ -192,4 +194,19 @@ class DevInsCompiler(private val myProject: Project, val file: DevInFile, val ed } } +class SymbolInsCommand(val myProject: Project, val prop: String) : + InsCommand { + override fun execute(): String? { + val result = DevInsSymbolProvider.all().map { + it.resolveSymbol(myProject, prop).joinToString("\n") + } + + if (result.isEmpty()) { + return " No symbol found: $prop" + } + + return result.joinToString("\n") + } +} + diff --git a/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/completion/BuiltinCommandProvider.kt b/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/completion/BuiltinCommandProvider.kt index 795b4efc6d..11b4833c81 100644 --- a/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/completion/BuiltinCommandProvider.kt +++ b/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/completion/BuiltinCommandProvider.kt @@ -23,7 +23,7 @@ enum class BuiltinCommand( * - Kotlin: [org.jetbrains.kotlin.idea.completion.KotlinCompletionContributor] * - Python: [com.jetbrains.python.codeInsight.completion.PyClassNameCompletionContributor] */ - SYMBOL("symbol", "[TODO] Read content by Java/Kotlin canonicalName", AllIcons.Actions.GroupBy, true), + SYMBOL("symbol", "[TODO] Read content by Java/Kotlin canonicalName", AllIcons.Actions.GroupBy, true, true), WRITE("write", "Write content to a file, /write:path/to/file:L1-L2", AllIcons.Actions.Edit, true, true), PATCH("patch", "Apply patch to a file, /patch:path/to/file", AllIcons.Vcs.Patch_file, false), RUN("run", "Run the content of a file", AllIcons.Actions.Execute, false), diff --git a/java/src/main/kotlin/cc/unitmesh/idea/provider/JavaCustomDevInsSymbolProvider.kt b/java/src/main/kotlin/cc/unitmesh/idea/provider/JavaCustomDevInsSymbolProvider.kt index 6ef109de99..4a8587b83f 100644 --- a/java/src/main/kotlin/cc/unitmesh/idea/provider/JavaCustomDevInsSymbolProvider.kt +++ b/java/src/main/kotlin/cc/unitmesh/idea/provider/JavaCustomDevInsSymbolProvider.kt @@ -9,10 +9,13 @@ import com.intellij.openapi.project.Project import com.intellij.psi.PsiManager import com.intellij.psi.PsiPackageStatement import com.intellij.psi.search.FileTypeIndex +import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.ProjectScope +import com.intellij.psi.search.PsiShortNamesCache import com.intellij.psi.util.PsiTreeUtil import com.intellij.util.SmartList + class JavaCustomDevInsSymbolProvider : DevInsSymbolProvider { override fun lookupSymbol( project: Project, @@ -43,4 +46,16 @@ class JavaCustomDevInsSymbolProvider : DevInsSymbolProvider { return lookupElements } + + override fun resolveSymbol(project: Project, symbol: String): Iterable { + val scope = GlobalSearchScope.allScope(project) + + // for class name only + val psiClasses = PsiShortNamesCache.getInstance(project).getClassesByName(symbol, scope) + if (psiClasses.isNotEmpty()) { + return psiClasses.map { it.qualifiedName!! } + } + + return emptyList() + } } diff --git a/src/main/kotlin/cc/unitmesh/devti/provider/devins/DevInsSymbolProvider.kt b/src/main/kotlin/cc/unitmesh/devti/provider/devins/DevInsSymbolProvider.kt index ad2dc5492e..def2081b82 100644 --- a/src/main/kotlin/cc/unitmesh/devti/provider/devins/DevInsSymbolProvider.kt +++ b/src/main/kotlin/cc/unitmesh/devti/provider/devins/DevInsSymbolProvider.kt @@ -11,13 +11,9 @@ import com.intellij.openapi.project.Project * - Completion will be triggered by like `/symbol:`, and the symbol provider will provide the completion for the symbol. * - Execution will be triggered by like `/symbol:java.lang.String`, all load children level elements, like `java.lang.String#length()` * - * For execution: - * - If parent is Root, the children will be packages - * - If parent is Package, the children will be classes - * - If parent is Class, the children will be methods and fields + * For execution, see in [DevInsSymbolProvider.resolveSymbol] */ interface DevInsSymbolProvider { - /** * Lookup canonical name for different language */ @@ -27,6 +23,15 @@ interface DevInsSymbolProvider { result: CompletionResultSet ): Iterable + /** + * Resolves the symbol for different programming languages. + * For example, in Java: + * - If the parent is Root, the children will be packages + * - If the parent is Package, the children will be classes + * - If the parent is Class, the children will be methods and fields + */ + fun resolveSymbol(project: Project, symbol: String): Iterable + companion object { private val EP_NAME: ExtensionPointName = ExtensionPointName("cc.unitmesh.customDevInsCompletionProvider")