Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 4 additions & 2 deletions example/lets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ commands:
test:
depends: [build]
cmd: echo Test


hello: echo Test

run:
depends: [test]
depends: [test, hello]
cmd: echo Run
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -20,16 +22,28 @@ open class LetsReferenceContributor : PsiReferenceContributor() {
object : PsiReferenceProvider() {
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> {
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<YAMLScalar>(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<YAMLScalar>(element) {
/**
Expand Down Expand Up @@ -60,15 +74,15 @@ class LetsMixinReference(element: YAMLScalar) : PsiReferenceBase<YAMLScalar>(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").
*/
private fun findMixinFile(project: Project, mixinPath: String): VirtualFile? {
// 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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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: [<caret>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)
}
}