diff --git a/CHANGELOG.md b/CHANGELOG.md index 77673f2..81ca5d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ # intellij-lets Changelog ## [Unreleased] +### Added + +- resolve commands in `depends` + ### Updated - make go to definition work for gitignore `mixins` files (with '-' (dash) at the beginning) diff --git a/example/lets.yaml b/example/lets.yaml index e095769..a366f3a 100644 --- a/example/lets.yaml +++ b/example/lets.yaml @@ -8,7 +8,9 @@ commands: test: depends: [build] cmd: echo Test - + + hello: echo Test + run: - depends: [test] + depends: [test, hello] cmd: echo Run diff --git a/src/main/kotlin/com/github/kindermax/intellijlets/LetsReferenceContributor.kt b/src/main/kotlin/com/github/kindermax/intellijlets/LetsReferenceContributor.kt index ba60aa5..34cd7aa 100644 --- a/src/main/kotlin/com/github/kindermax/intellijlets/LetsReferenceContributor.kt +++ b/src/main/kotlin/com/github/kindermax/intellijlets/LetsReferenceContributor.kt @@ -10,7 +10,9 @@ import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.util.PsiTreeUtil import com.intellij.util.PathUtil import com.intellij.util.ProcessingContext +import org.jetbrains.yaml.psi.YAMLFile import org.jetbrains.yaml.psi.YAMLKeyValue +import org.jetbrains.yaml.psi.YAMLMapping import org.jetbrains.yaml.psi.YAMLScalar open class LetsReferenceContributor : PsiReferenceContributor() { @@ -20,16 +22,28 @@ open class LetsReferenceContributor : PsiReferenceContributor() { object : PsiReferenceProvider() { override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array { val yamlKeyValue = PsiTreeUtil.getParentOfType(element, YAMLKeyValue::class.java) ?: return emptyArray() - if (yamlKeyValue.keyText == "mixins") { - return arrayOf(LetsMixinReference(element as YAMLScalar)) + + return when (yamlKeyValue.keyText) { + "mixins" -> arrayOf(LetsMixinReference(element as YAMLScalar)) + "depends" -> arrayOf(LetsDependsReference(element as YAMLScalar)) + else -> emptyArray() } - return emptyArray() } } ) } } +class LetsDependsReference(element: YAMLScalar) : PsiReferenceBase(element) { + override fun resolve(): PsiElement? { + val commandName = myElement.textValue // Extracts the command name inside `depends` + + // Locate the command declaration in the same YAML file + val yamlFile = myElement.containingFile as? YAMLFile ?: return null + return PsiTreeUtil.findChildrenOfType(yamlFile, YAMLKeyValue::class.java) + .firstOrNull { it.keyText == commandName && it.parent is YAMLMapping } + } +} class LetsMixinReference(element: YAMLScalar) : PsiReferenceBase(element) { /** @@ -60,7 +74,7 @@ class LetsMixinReference(element: YAMLScalar) : PsiReferenceBase(ele return yamlFiles.toTypedArray() } - /** + /** * Searches for the mixin file anywhere in the project. * Supports both top-level files ("lets.build.yaml") and nested files ("lets/lets.docs.yaml"). */ @@ -68,7 +82,7 @@ class LetsMixinReference(element: YAMLScalar) : PsiReferenceBase(ele // Normalize paths (handle both "lets.mixin.yaml" and "lets/lets.mixin.yaml") val normalizedPath = mixinPath.trimStart('/') // Normalize gitignored files (e.g. "-lets.mixin.yaml" -> "lets.mixin.yaml") - .removePrefix("-") + .removePrefix("-") // Look for an exact match in the project return FilenameIndex.getVirtualFilesByName( diff --git a/src/test/kotlin/com/github/kindermax/intellijlets/reference/ReferenceTest.kt b/src/test/kotlin/com/github/kindermax/intellijlets/reference/ReferenceTest.kt index 5aaae9a..6f6ef99 100644 --- a/src/test/kotlin/com/github/kindermax/intellijlets/reference/ReferenceTest.kt +++ b/src/test/kotlin/com/github/kindermax/intellijlets/reference/ReferenceTest.kt @@ -2,6 +2,7 @@ package com.github.kindermax.intellijlets.reference import com.intellij.psi.PsiFile import com.intellij.testFramework.fixtures.BasePlatformTestCase +import org.jetbrains.yaml.psi.YAMLKeyValue open class MinixsReferenceTest : BasePlatformTestCase() { fun testMixinFileReference() { @@ -120,3 +121,34 @@ open class MinixsReferenceTest : BasePlatformTestCase() { } } +open class DependsReferenceTest : BasePlatformTestCase() { + fun testDependsCommandReference() { + myFixture.configureByText( + "lets.yaml", + """ + shell: bash + + commands: + test: + cmd: echo Test + + run: + depends: [test] + cmd: echo Run + """.trimIndent() + ) + + val ref = myFixture.getReferenceAtCaretPosition("lets.yaml") + assertNotNull("Reference should not be null", ref) + + val resolvedElement = ref!!.resolve() + assertNotNull("Resolved element should not be null", resolvedElement) + + val resolvedFile = resolvedElement?.containingFile + assertEquals("lets.yaml", resolvedFile?.name) + + val resolvedKey = resolvedElement as? YAMLKeyValue + assertNotNull("Resolved element should be a YAMLKeyValue", resolvedKey) + assertEquals("test", resolvedKey!!.keyText) + } +}