From b80eda5dca72932d8917e28a7c9fa015ca385e6f Mon Sep 17 00:00:00 2001 From: "m.kindritskiy" Date: Fri, 7 Mar 2025 16:22:30 +0200 Subject: [PATCH] inject shell lang into cmd --- README.md | 9 ++++- example/lets.yaml | 12 ++++-- gradle.properties | 2 +- .../intellijlets/LetsBashInjector.kt | 37 +++++++++++++++++++ src/main/resources/META-INF/plugin.xml | 2 + src/main/resources/META-INF/sh.xml | 5 +++ 6 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 src/main/kotlin/com/github/kindermax/intellijlets/LetsBashInjector.kt create mode 100644 src/main/resources/META-INF/sh.xml diff --git a/README.md b/README.md index 5ff2618..720a336 100644 --- a/README.md +++ b/README.md @@ -17,14 +17,19 @@ File type recognition for `lets.yaml` and `lets.*.yaml` configs - [x] Complete commands in `depends` with code snippet - [ ] Complete commands in `depends` from mixins - [ ] Complete env mode in `env` with code snippet + - [ ] Complete environment variables in cmd scripts - **Go To Definition** - [x] Navigate to definitions of `mixins` files - [x] Navigate to definitions of optional `mixins` files (with - at the beginning) - [x] Navigate to definitions of `mixins` remote files (as http links) - - [ ] Navigate to definitions of commands in `depends` + - [x] Navigate to definitions of commands in `depends` - [ ] Navigate to definitions of commands in `depends` from mixins - **Highlighting** - - [ ] Highlighting for shell script in cmd + - [x] Highlighting for shell script in cmd +- **Diagnostic** + - [ ] Diagnostic for missing `depends` commands + - [ ] Diagnostic for missing `mixins` files + - [ ] Diagnostic for errors in shell script diff --git a/example/lets.yaml b/example/lets.yaml index a366f3a..1e0a372 100644 --- a/example/lets.yaml +++ b/example/lets.yaml @@ -7,10 +7,16 @@ mixins: commands: test: depends: [build] - cmd: echo Test + cmd: echo ${LETS_COMMAND_NAME} - hello: echo Test + hello: echo Hello run: depends: [test, hello] - cmd: echo Run + cmd: | + set -ex + echo Run + echo Rff + if [ -n "${LE}" ]; then + exit 1 + fi diff --git a/gradle.properties b/gradle.properties index 42e2d15..e6fe09f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,7 +20,7 @@ platformDownloadSources = true # Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 platformPlugins = # Example: platformBundledPlugins = com.intellij.java -platformBundledPlugins = org.jetbrains.plugins.yaml +platformBundledPlugins = org.jetbrains.plugins.yaml,com.jetbrains.sh # Opt-out flag for bundling Kotlin standard library. # See https://kotlinlang.org/docs/reference/using-gradle.html#dependency-on-the-standard-library for details. diff --git a/src/main/kotlin/com/github/kindermax/intellijlets/LetsBashInjector.kt b/src/main/kotlin/com/github/kindermax/intellijlets/LetsBashInjector.kt new file mode 100644 index 0000000..4249be8 --- /dev/null +++ b/src/main/kotlin/com/github/kindermax/intellijlets/LetsBashInjector.kt @@ -0,0 +1,37 @@ +package com.github.kindermax.intellijlets + +import com.intellij.lang.Language +import com.intellij.lang.injection.MultiHostInjector +import com.intellij.lang.injection.MultiHostRegistrar +import com.intellij.openapi.util.TextRange +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiLanguageInjectionHost +import com.intellij.psi.util.PsiTreeUtil +import com.intellij.refactoring.suggested.endOffset +import com.intellij.refactoring.suggested.startOffset +import org.jetbrains.yaml.psi.YAMLKeyValue +import org.jetbrains.yaml.psi.YAMLScalar + +class LetsBashInjector : MultiHostInjector { + override fun elementsToInjectIn(): List> { + return listOf(YAMLScalar::class.java) // We only care about YAML string values + } + + override fun getLanguagesToInject(registrar: MultiHostRegistrar, context: PsiElement) { + // Ensure we are in a `cmd` field inside `commands` + val keyValue = PsiTreeUtil.getParentOfType(context, YAMLKeyValue::class.java) ?: return + if (keyValue.keyText == "cmd") { + val bashLanguage = Language.findLanguageByID("Shell Script") ?: return + val text = context.text + var startOffset = 0; + if (text.startsWith("|")) { + startOffset += 1 + } + val endOffset = keyValue.endOffset - (keyValue.value?.startOffset ?: keyValue.endOffset) + val injectionTextRange = TextRange(startOffset, endOffset) + registrar.startInjecting(bashLanguage) + .addPlace(null, null, context as PsiLanguageInjectionHost, injectionTextRange) + .doneInjecting() + } + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index e847e5c..9e20616 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -10,6 +10,8 @@ com.intellij.modules.platform org.jetbrains.plugins.yaml + com.jetbrains.sh + + + + + \ No newline at end of file