Open Cottand opened 2 months ago
Hi, I agree that language injections would be a nice feature.
2. Support 'comments as injection markers' (a lot like the
@Language(...)
annotation in Java or Kotlin), for more permanent injections
This can probably be separated into two parts. Comments next to the string, and comments on the option declaration when using Nix modules. However, the second part would be tricky and work only when we can resolve references of Nix Modules.
I find I cannot edit PSI elements because they are all code-generated. Would moving them out be an opation?
You cannot modify the generated classes, but you can modify the sources from which they are generated. The following should work:
diff --git a/core/src/main/lang/Nix.bnf b/core/src/main/lang/Nix.bnf
index 5aba71c..948fdad 100644
--- a/core/src/main/lang/Nix.bnf
+++ b/core/src/main/lang/Nix.bnf
@@ -24,6 +24,10 @@
// no one really needs to know that + - * / are expected at any offset
consumeTokenMethod("expr_op.*")="consumeTokenFast"
+ // Make Strings to Language Injection Hosts
+ implements("string")="com.intellij.psi.PsiLanguageInjectionHost"
+ mixin("string")="org.nixos.idea.psi.impl.AbstractNixString"
+
tokens = [
// This list does not contain all tokens. This list only defines the debug
// names for tokens which have a distinct text representation. Other tokens
You would then have to create the abstract class org.nixos.idea.psi.impl.AbstractNixString
which should extend AbstractNixPsiElement
or NixExprStringImpl
(doesn't really matter which of the two, but I would prefer the first) and the NixString
interface. Within this abstract class, you can implement the methods for PsiLanguageInjectionHost
.
Note that there is already NixStringUtil
for unescaping strings. For the other direction, the class currently only supports escaping “normal” strings. You properly have to extend the class to support escaping in indented strings.
EDIT: And there is also already NixElementFactory
, which can be used (maybe with slight modification) to create new instances of NixString
.
EDIT 2: NixStringUtil.parse
does not yet remove the common indentation of indented strings.
Note that you may have to handle string interpolation somehow. I think IntelliJ has some support for string interpolation in such cases, but I don't know if there are any special steps required. You could probably also limit support for language injection to strings without interpolations for now, in case that would be much easier.
thanks, your diff should be exactly what I need to get unblocked. I will get to work this weekend and report back 🙏
as for string interpolation, I'll see how it looks without doing anything special and see from there. Thanks again
I would love support for language injections. I think there is value for this in Nix specificially, because in NixOS and Nix derivations we deal with other languages inside Nix strings quite often (bash in derivations, TOML and YAML in configs...).
I think there are two steps to this:
NixIndString
@Language(...)
annotation in Java or Kotlin), for more permanent injectionsI tried to follow the example to implement the former myself, but I find I cannot edit PSI elements because they are all code-generated. Would moving them out be an opation?