Repository: nix-community/nixvim
Pull request #3087: plugins/faust: init
Author: login: GaetanLepage
Created: 2025-03-20T09:50:09Z | Merged: 2025-03-20T16:50:39Z

Add support for [faust.nvim](https://github.com/madskjeldgaard/faust-nvim), a plugin for writing Faust DSP code.

Fixes #2997


Linked issue #2997: [PLUGIN REQUEST] faust-nvim
| Field    | Description |
|----------|-------------|
| Plugin   | `faust-nvim`  | <!-- Plugin NixVim should support -->
| Homepage | `https://github.com/madskjeldgaard/faust-nvim`     | <!-- URL to the plugin repository -->
| Nixpkgs  | `false` | <!-- Nixpkgs URL or `false` -->

## Extra Information

FAUST is a functional programming language for real-time stream processing: https://faust.grame.fr/

We might want to pay special attention to these options:

https://github.com/madskjeldgaard/faust-nvim?tab=readme-ov-file#options

^we could probably default most of these to the nixpkgs `faust` package locations.
Linked issue comments: user: login: GaetanLepage
created_at: 2025-02-18T10:06:19Z
body: Opened https://github.com/NixOS/nixpkgs/pull/383070.
author_association: MEMBER

Diff:
diff --git a/plugins/by-name/faust/default.nix b/plugins/by-name/faust/default.nix
new file mode 100644
index 0000000000..026e80e3dd
--- /dev/null
+++ b/plugins/by-name/faust/default.nix
@@ -0,0 +1,59 @@
+{ lib, pkgs, ... }:
+let
+  globalPrefix = "faust";
+in
+lib.nixvim.plugins.mkNeovimPlugin {
+  name = "faust";
+  packPathName = "faust-nvim";
+  package = "faust-nvim";
+
+  maintainers = [ lib.maintainers.GaetanLepage ];
+
+  # Configuration is done through globals vim.g.faust*
+  hasSettings = false;
+  extraOptions = {
+    faustPackage = lib.mkOption {
+      type = with lib.types; nullOr package;
+      default = pkgs.faust;
+      defaultText = lib.literalExpression "pkgs.faust";
+      description = ''
+        If non-null, the provided package will be used to initialize the plugin's settings:
+        ```nix
+          settings = {
+            _examples_dir = "''${cfg.faustPackage}/share/faust/examples";
+            "2appls_dir" = "''${cfg.faustPackage}/bin";
+            lib_dir = "''${cfg.faustPackage}/share/faust/";
+          };
+        ```
+      '';
+    };
+
+    settings = lib.nixvim.plugins.vim.mkSettingsOption {
+      inherit globalPrefix;
+      name = "faust";
+      example = {
+        _examples_dir = "/usr/share/faust/examples";
+        "2appls_dir" = "/bin/";
+        lib_dir = "/usr/share/faust/";
+      };
+    };
+  };
+
+  callSetup = false;
+  extraConfig = cfg: {
+    plugins.faust = {
+      luaConfig.content = ''
+        require('faust-nvim')
+        require('faust-nvim').load_snippets()
+      '';
+
+      # Explicitly provide the paths to the faust components
+      settings = lib.mkIf (cfg.faustPackage != null) {
+        _examples_dir = lib.mkDefault "${cfg.faustPackage}/share/faust/examples";
+        "2appls_dir" = lib.mkDefault (lib.getBin cfg.faustPackage);
+        lib_dir = lib.mkDefault "${cfg.faustPackage}/share/faust/";
+      };
+    };
+    globals = lib.nixvim.applyPrefixToAttrs globalPrefix cfg.settings;
+  };
+}
diff --git a/tests/test-sources/plugins/by-name/faust/default.nix b/tests/test-sources/plugins/by-name/faust/default.nix
new file mode 100644
index 0000000000..d8b44d7400
--- /dev/null
+++ b/tests/test-sources/plugins/by-name/faust/default.nix
@@ -0,0 +1,5 @@
+{
+  empty = {
+    plugins.faust.enable = true;
+  };
+}


Reviews:
user: login: MattSturgeon
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T14:52:50Z
user: login: GaetanLepage
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T14:56:13Z
user: login: MattSturgeon
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T15:14:06Z
user: login: MattSturgeon
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T15:15:27Z
user: login: MattSturgeon
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T15:17:05Z
user: login: GaetanLepage
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T15:28:05Z
user: login: MattSturgeon
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-20T16:39:44Z

Review comments:
diff_hunk: @@ -0,0 +1,46 @@
+{ lib, pkgs, ... }:
+let
+  globalPrefix = "faust";
+in
+lib.nixvim.plugins.mkNeovimPlugin {
+  name = "faust";
+  packPathName = "faust-nvim";
+  package = "faust-nvim";
+
+  maintainers = [ lib.maintainers.GaetanLepage ];
+
+  # Configuration is done through globals vim.g.faust*
path: plugins/by-name/faust/default.nix
user: login: MattSturgeon
body: I'm confused. Why are we using `mkNeovimPlugin` and then configuring it to behave like `mkVimPlugin`?
created_at: 2025-03-20T14:52:50Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,46 @@
+{ lib, pkgs, ... }:
+let
+  globalPrefix = "faust";
+in
+lib.nixvim.plugins.mkNeovimPlugin {
+  name = "faust";
+  packPathName = "faust-nvim";
+  package = "faust-nvim";
+
+  maintainers = [ lib.maintainers.GaetanLepage ];
+
+  # Configuration is done through globals vim.g.faust*
path: plugins/by-name/faust/default.nix
user: login: GaetanLepage
body: I hesitated, but using `mkNeovimPlugin` allows us putting the lua configuration code in `luaConfig.content`. This permits lazy loading too.
created_at: 2025-03-20T14:56:13Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,46 @@
+{ lib, pkgs, ... }:
+let
+  globalPrefix = "faust";
+in
+lib.nixvim.plugins.mkNeovimPlugin {
+  name = "faust";
+  packPathName = "faust-nvim";
+  package = "faust-nvim";
+
+  maintainers = [ lib.maintainers.GaetanLepage ];
+
+  # Configuration is done through globals vim.g.faust*
+  hasSettings = false;
+  extraOptions = {
+    faustPackage = lib.mkPackageOption pkgs "faust" {
+      nullable = true;
+    };
+
+    settings = lib.nixvim.plugins.vim.mkSettingsOption {
+      inherit globalPrefix;
+      name = "faust";
+      example = {
+        _examples_dir = "/usr/share/faust/examples";
+        "2appls_dir" = "/bin/";
+        lib_dir = "/usr/share/faust/";
+      };
+    };
+  };
+
+  callSetup = false;
+  extraConfig = cfg: {
+    plugins.faust = {
+      luaConfig.content = ''
+        require('faust-nvim')
+        require('faust-nvim').load_snippets()
+      '';
+
+      settings = lib.mkIf (cfg.faustPackage != null) {
+        _examples_dir = "${cfg.faustPackage}/share/faust/examples";
+        "2appls_dir" = lib.getBin cfg.faustPackage;
+        lib_dir = "${cfg.faustPackage}/share/faust/";
+      };
+    };
+    globals = lib.nixvim.applyPrefixToAttrs globalPrefix (cfg.settings or { });
path: plugins/by-name/faust/default.nix
user: login: MattSturgeon
body: ```suggestion
    globals = lib.nixvim.applyPrefixToAttrs globalPrefix cfg.settings;
```

The `settings` attr should always exist
created_at: 2025-03-20T15:14:06Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,46 @@
+{ lib, pkgs, ... }:
+let
+  globalPrefix = "faust";
+in
+lib.nixvim.plugins.mkNeovimPlugin {
+  name = "faust";
+  packPathName = "faust-nvim";
+  package = "faust-nvim";
+
+  maintainers = [ lib.maintainers.GaetanLepage ];
+
+  # Configuration is done through globals vim.g.faust*
+  hasSettings = false;
+  extraOptions = {
+    faustPackage = lib.mkPackageOption pkgs "faust" {
+      nullable = true;
+    };
+
+    settings = lib.nixvim.plugins.vim.mkSettingsOption {
+      inherit globalPrefix;
+      name = "faust";
+      example = {
+        _examples_dir = "/usr/share/faust/examples";
+        "2appls_dir" = "/bin/";
+        lib_dir = "/usr/share/faust/";
+      };
+    };
+  };
+
+  callSetup = false;
+  extraConfig = cfg: {
+    plugins.faust = {
+      luaConfig.content = ''
+        require('faust-nvim')
+        require('faust-nvim').load_snippets()
+      '';
+
+      settings = lib.mkIf (cfg.faustPackage != null) {
+        _examples_dir = "${cfg.faustPackage}/share/faust/examples";
+        "2appls_dir" = lib.getBin cfg.faustPackage;
+        lib_dir = "${cfg.faustPackage}/share/faust/";
+      };
path: plugins/by-name/faust/default.nix
user: login: MattSturgeon
body: I'm not 100% what this is doing (maybe a comment would help?).

Should this behaviour be documented in the `faustPackage` option's description?
created_at: 2025-03-20T15:15:27Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,46 @@
+{ lib, pkgs, ... }:
+let
+  globalPrefix = "faust";
+in
+lib.nixvim.plugins.mkNeovimPlugin {
+  name = "faust";
+  packPathName = "faust-nvim";
+  package = "faust-nvim";
+
+  maintainers = [ lib.maintainers.GaetanLepage ];
+
+  # Configuration is done through globals vim.g.faust*
path: plugins/by-name/faust/default.nix
user: login: MattSturgeon
body: Hm. I missed that this plugin has some lua-based setup _in addition_ to globals-based settings.

I think this approach is fine, then.
created_at: 2025-03-20T15:17:03Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,46 @@
+{ lib, pkgs, ... }:
+let
+  globalPrefix = "faust";
+in
+lib.nixvim.plugins.mkNeovimPlugin {
+  name = "faust";
+  packPathName = "faust-nvim";
+  package = "faust-nvim";
+
+  maintainers = [ lib.maintainers.GaetanLepage ];
+
+  # Configuration is done through globals vim.g.faust*
+  hasSettings = false;
+  extraOptions = {
+    faustPackage = lib.mkPackageOption pkgs "faust" {
+      nullable = true;
+    };
+
+    settings = lib.nixvim.plugins.vim.mkSettingsOption {
+      inherit globalPrefix;
+      name = "faust";
+      example = {
+        _examples_dir = "/usr/share/faust/examples";
+        "2appls_dir" = "/bin/";
+        lib_dir = "/usr/share/faust/";
+      };
+    };
+  };
+
+  callSetup = false;
+  extraConfig = cfg: {
+    plugins.faust = {
+      luaConfig.content = ''
+        require('faust-nvim')
+        require('faust-nvim').load_snippets()
+      '';
+
+      settings = lib.mkIf (cfg.faustPackage != null) {
+        _examples_dir = "${cfg.faustPackage}/share/faust/examples";
+        "2appls_dir" = lib.getBin cfg.faustPackage;
+        lib_dir = "${cfg.faustPackage}/share/faust/";
+      };
path: plugins/by-name/faust/default.nix
user: login: GaetanLepage
body: ![image](https://github.com/user-attachments/assets/741f11c9-2925-46e2-ab26-598ff5bd5eab)
created_at: 2025-03-20T15:28:05Z
author_association: MEMBER

PR comments:
user: login: GaetanLepage
created_at: 2025-03-20T16:50:26Z
body: @mergify queue
author_association: MEMBER
user: login: mergify[bot]
created_at: 2025-03-20T16:50:32Z
body: > queue

#### ✅ The pull request has been merged automatically

<details>

The pull request has been merged automatically at *d44b33a1ea1a3e584a8c93164dbe0ba2ad4f3a13*

</details>


<!---
DO NOT EDIT
-*- Mergify Payload -*-
{"command": "queue", "conclusion": "success", "action_is_running": true}
-*- Mergify Payload End -*-
-->
author_association: CONTRIBUTOR
user: login: mergify[bot]
created_at: 2025-03-20T16:50:39Z
body: This pull request, with head sha `d44b33a1ea1a3e584a8c93164dbe0ba2ad4f3a13`, has been successfully merged with fast-forward by Mergify.

<details>
  <summary>This pull request will be automatically closed by GitHub.</summary>

As soon as GitHub detects that the sha `d44b33a1ea1a3e584a8c93164dbe0ba2ad4f3a13` is part of the `main` branch, it will mark this pull request as merged.

It is possible for this pull request to remain open if this detection does not happen, this usually happens when a force-push is done on this branch `faust`, this means GitHub will fail to detect the merge.
</details>

author_association: CONTRIBUTOR