Skip to content

Commit

Permalink
Complete env vars from global env in cmd scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
kindermax committed Mar 8, 2025
1 parent 34aa0bc commit ad7370d
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 5 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ File type recognition for `lets.yaml` and `lets.*.yaml` configs
- [ ] Complete env mode in `env` with code snippet
- [x] Complete `LETS*` environment variables in cmd scripts
- [ ] Complete environment variables for checksum
- [ ] Complete environment variables from global and command `env` in cmd scripts
- [x] Complete environment variables from global and command `env` in cmd scripts
- [ ] Complete environment variables in `args`
- **Go To Definition**
- [x] Navigate to definitions of `mixins` files
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.intellij.util.ProcessingContext
import org.jetbrains.yaml.psi.YAMLKeyValue
import org.jetbrains.yaml.psi.YAMLScalar
import org.jetbrains.yaml.psi.YAMLMapping
import org.jetbrains.yaml.psi.YAMLFile

import com.intellij.lang.injection.InjectedLanguageManager
import com.intellij.psi.PsiFile
Expand All @@ -24,6 +25,7 @@ open class LetsEnvVariableCompletionContributorBase : CompletionContributor() {
}

protected fun completeCmdEnvVariables(
parameters: CompletionParameters,
result: CompletionResultSet,
cmdKeyValue: YAMLKeyValue?,
prefixText: String,
Expand All @@ -38,14 +40,15 @@ open class LetsEnvVariableCompletionContributorBase : CompletionContributor() {
val extractedOptions = extractOptionNames(optionsText)

when {
prefixText.endsWith("$") -> addEnvVariableCompletions(result, "$", extractedOptions)
prefixText.endsWith("\$L") -> addEnvVariableCompletions(result, "\$L", extractedOptions)
prefixText.endsWith("\${") -> addEnvVariableCompletions(result, "\${", extractedOptions)
prefixText.endsWith("\${L") -> addEnvVariableCompletions(result, "\${L", extractedOptions)
prefixText.endsWith("$") -> addEnvVariableCompletions(parameters, result, "$", extractedOptions)
prefixText.endsWith("\$L") -> addEnvVariableCompletions(parameters, result, "\$L", extractedOptions)
prefixText.endsWith("\${") -> addEnvVariableCompletions(parameters, result, "\${", extractedOptions)
prefixText.endsWith("\${L") -> addEnvVariableCompletions(parameters, result, "\${L", extractedOptions)
}
}

private fun addEnvVariableCompletions(
parameters: CompletionParameters,
result: CompletionResultSet,
prefix: String,
extractedOptions: Set<String>
Expand All @@ -56,6 +59,14 @@ open class LetsEnvVariableCompletionContributorBase : CompletionContributor() {
prefixMatcher.addElement(createEnvVariableLookupElement(it))
}

val globalEnvVars = (parameters.originalFile as? YAMLFile)?.let {
LetsPsiUtils.getGlobalEnvVariables(it)
} ?: emptySet()

globalEnvVars.forEach {
prefixMatcher.addElement(createEnvVariableLookupElement(it))
}

extractedOptions.forEach { option ->
prefixMatcher.addElement(createEnvVariableLookupElement("LETSOPT_${option.uppercase()}"))
prefixMatcher.addElement(createEnvVariableLookupElement("LETSCLI_${option.uppercase()}"))
Expand Down Expand Up @@ -109,6 +120,7 @@ class LetsEnvVariableCompletionContributor : LetsEnvVariableCompletionContributo
val prefixText = parameters.editor.document.getText(TextRange(lineOffset, caret.offset))

completeCmdEnvVariables(
parameters,
result,
keyValue,
prefixText,
Expand Down Expand Up @@ -160,6 +172,7 @@ class LetsEnvVariableShellScriptCompletionContributor : LetsEnvVariableCompletio
val prefixText = parameters.editor.document.getText(TextRange(parameters.offset - 1, parameters.offset))

completeCmdEnvVariables(
parameters,
result,
keyValue,
prefixText,
Expand Down
10 changes: 10 additions & 0 deletions src/main/kotlin/com/github/kindermax/intellijlets/LetsPsiUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,14 @@ object LetsPsiUtils {

return usedKeywords
}

fun getGlobalEnvVariables(yamlFile: YAMLFile): List<String> {
val envKey = PsiTreeUtil.findChildrenOfType(yamlFile, YAMLKeyValue::class.java)
.firstOrNull { it.keyText == "env" } ?: return emptyList()

return (envKey.value as? YAMLMapping)
?.keyValues
?.mapNotNull { it.keyText }
?: emptyList()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -193,4 +193,25 @@ class LetsPsiUtilsTest : BasePlatformTestCase() {
val usedKeywords = LetsPsiUtils.getUsedKeywords(file as YAMLFile)
assertEquals(usedKeywords.sorted(), listOf("shell", "mixins", "before", "commands").sorted())
}

fun testFindGlobalEnv() {
val file = myFixture.configureByText(
"lets.yaml",
"""
shell: bash
env:
OS: Darwin
DEV: true
commands:
world:
cmd: echo World
env:
FOO: BAR
""".trimIndent()
)

val envKeys = LetsPsiUtils.getGlobalEnvVariables(file as YAMLFile)
assertEquals(envKeys.toSet(), setOf("OS", "DEV"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,26 @@ open class CompleteEnvTest : BasePlatformTestCase() {

assertEquals(expected, variants?.toSet())
}

fun testCompleteFromGlobalEnv() {
myFixture.configureByText(
"lets.yaml",
"""
shell: bash
env:
DEV: true
commands:
run:
cmd: Echo $<caret>
""".trimIndent()
)
val variants = myFixture.getCompletionVariants("lets.yaml")
assertNotNull(variants)

val expected = BUILTIN_ENV_VARIABLES.map { "\${$it}" }.toMutableSet()
expected.add("\${DEV}")

assertEquals(expected, variants?.toSet())
}
}

0 comments on commit ad7370d

Please sign in to comment.