Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Language injections #81

Open
cottand opened this issue Jun 12, 2024 · 2 comments
Open

Support Language injections #81

cottand opened this issue Jun 12, 2024 · 2 comments

Comments

@cottand
Copy link
Contributor

cottand commented Jun 12, 2024

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:

  1. Support the 'inject language here' action
    • I think all that's needed is something like this in NixIndString
    • I also think this is not a lot of effort for good value, because other IDEs (ahem VSCode) cannot do language injections as well as IDEA.
  2. Support 'comments as injection markers' (a lot like the @Language(...) annotation in Java or Kotlin), for more permanent injections
    • This is trickier and would involve following this guide

I 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?

@JojOatXGME
Copy link
Contributor

JojOatXGME commented Jun 13, 2024

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.

@cottand
Copy link
Contributor Author

cottand commented Jun 14, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants