From a6d7278ed256f6ea60a2b339f645f75f8f35998f Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Thu, 18 Jul 2024 12:04:46 +0100 Subject: [PATCH 1/9] modules/output: rename `path` -> `target` Attempt to be consistent with `extraFiles` and other file types. --- modules/output.nix | 5 ++++- modules/top-level/files/default.nix | 2 +- modules/top-level/files/submodule.nix | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/output.nix b/modules/output.nix index 0cfdd5b7b6..e9f381cfbf 100644 --- a/modules/output.nix +++ b/modules/output.nix @@ -78,9 +78,10 @@ in description = "Whether the generated file is a vim or a lua file"; }; - path = mkOption { + target = mkOption { type = types.str; description = "Path of the file relative to the config directory"; + default = "init.lua"; }; content = mkOption { @@ -97,6 +98,8 @@ in }; }; + imports = [ (lib.mkRenamedOptionModule [ "path" ] [ "target" ]) ]; + config = let contentLua = '' diff --git a/modules/top-level/files/default.nix b/modules/top-level/files/default.nix index c8a3d24840..f52bd757fd 100644 --- a/modules/top-level/files/default.nix +++ b/modules/top-level/files/default.nix @@ -64,7 +64,7 @@ in extraFiles = lib.mkDerivedConfig options.files ( lib.mapAttrs' ( _: file: { - name = file.path; + name = file.target; value.source = file.plugin; } ) diff --git a/modules/top-level/files/submodule.nix b/modules/top-level/files/submodule.nix index d231cf6a87..bf0afbea85 100644 --- a/modules/top-level/files/submodule.nix +++ b/modules/top-level/files/submodule.nix @@ -19,7 +19,7 @@ derivationName = "nvim-" + lib.replaceStrings [ "/" ] [ "-" ] name; in { - path = lib.mkDefault name; + target = lib.mkDefault name; type = lib.mkDefault (if lib.hasSuffix ".vim" name then "vim" else "lua"); # No need to use mkDerivedConfig; this option is readOnly. plugin = helpers.writeLua derivationName config.content; From 0c51668e5485fdb5a3f97e520b3b8d1ca1871db6 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Thu, 18 Jul 2024 12:41:46 +0100 Subject: [PATCH 2/9] modules/output: introduce `finalConfig` option Replaces the `plugin` option used in files submodules and the `initPath` option used at the top-level. --- modules/output.nix | 22 +++++++++++++++-- modules/top-level/files/default.nix | 2 +- modules/top-level/files/submodule.nix | 34 ++++++++------------------- modules/top-level/output.nix | 21 +++++++---------- wrappers/_shared.nix | 4 ++-- 5 files changed, 42 insertions(+), 41 deletions(-) diff --git a/modules/output.nix b/modules/output.nix index e9f381cfbf..2f403f19e6 100644 --- a/modules/output.nix +++ b/modules/output.nix @@ -1,4 +1,9 @@ -{ lib, config, ... }: +{ + config, + lib, + helpers, + ... +}: with lib; let pluginWithConfigType = types.submodule { @@ -74,7 +79,8 @@ in "vim" "lua" ]; - default = "lua"; + default = if lib.hasSuffix ".vim" config.target then "vim" else "lua"; + defaultText = lib.literalMD ''`"lua"` unless `config.target` ends with `".vim"`''; description = "Whether the generated file is a vim or a lua file"; }; @@ -91,6 +97,13 @@ in visible = false; }; + finalConfig = mkOption { + type = types.package; + description = "The config file written as a derivation"; + internal = true; + # FIXME: can't be readOnly because we override it in top-level modules + }; + extraLuaPackages = mkOption { type = types.functionTo (types.listOf types.package); description = "Extra lua packages to include with neovim"; @@ -102,6 +115,10 @@ in config = let + derivationName = "nvim-" + lib.replaceStrings [ "/" ] [ "-" ] config.target; + + writer = if config.type == "lua" then helpers.writeLua else pkgs.writeText; + contentLua = '' ${config.extraConfigLuaPre} vim.cmd([[ @@ -124,5 +141,6 @@ in in { content = if config.type == "lua" then contentLua else contentVim; + finalConfig = writer derivationName config.content; }; } diff --git a/modules/top-level/files/default.nix b/modules/top-level/files/default.nix index f52bd757fd..410181cb77 100644 --- a/modules/top-level/files/default.nix +++ b/modules/top-level/files/default.nix @@ -65,7 +65,7 @@ in lib.mapAttrs' ( _: file: { name = file.target; - value.source = file.plugin; + value.source = file.finalConfig; } ) ); diff --git a/modules/top-level/files/submodule.nix b/modules/top-level/files/submodule.nix index bf0afbea85..3e9f025f75 100644 --- a/modules/top-level/files/submodule.nix +++ b/modules/top-level/files/submodule.nix @@ -1,27 +1,13 @@ +{ name, lib, ... }: { - name, - config, - lib, - helpers, - ... -}: -{ - options = { - plugin = lib.mkOption { - type = lib.types.package; - description = "A derivation with the content of the file in it"; - readOnly = true; - internal = true; - }; + imports = [ + (lib.mkRenamedOptionModule [ + "plugin" + "finalConfig" + ]) + ]; + + config = { + target = lib.mkDefault name; }; - config = - let - derivationName = "nvim-" + lib.replaceStrings [ "/" ] [ "-" ] name; - in - { - target = lib.mkDefault name; - type = lib.mkDefault (if lib.hasSuffix ".vim" name then "vim" else "lua"); - # No need to use mkDerivedConfig; this option is readOnly. - plugin = helpers.writeLua derivationName config.content; - }; } diff --git a/modules/top-level/output.nix b/modules/top-level/output.nix index 268316fcb8..62adabe56b 100644 --- a/modules/top-level/output.nix +++ b/modules/top-level/output.nix @@ -54,13 +54,6 @@ with lib; readOnly = true; }; - initPath = mkOption { - type = types.str; - description = "The path to the `init.lua` file."; - readOnly = true; - visible = false; - }; - printInitPackage = mkOption { type = types.package; description = "A tool to show the content of the generated `init.lua` file."; @@ -69,6 +62,12 @@ with lib; }; }; + imports = [ + (lib.mkRemovedOptionModule [ "initPath" ] '' + Use `finalConfig' instead. + '') + ]; + config = let defaultPlugin = { @@ -118,11 +117,9 @@ with lib; '') + config.content; - init = helpers.writeLua "init.lua" customRC; - extraWrapperArgs = builtins.concatStringsSep " " ( (optional (config.extraPackages != [ ]) ''--prefix PATH : "${makeBinPath config.extraPackages}"'') - ++ (optional config.wrapRc ''--add-flags -u --add-flags "${init}"'') + ++ (optional config.wrapRc ''--add-flags -u --add-flags "${config.finalConfig}"'') ); wrappedNeovim = pkgs.wrapNeovimUnstable config.package ( @@ -136,13 +133,13 @@ with lib; { type = lib.mkForce "lua"; finalPackage = wrappedNeovim; - initPath = "${init}"; + finalConfig = lib.mkForce (helpers.writeLua config.target customRC); printInitPackage = pkgs.writeShellApplication { name = "nixvim-print-init"; runtimeInputs = [ pkgs.bat ]; text = '' - bat --language=lua "${init}" + bat --language=lua "${config.finalConfig}" ''; }; diff --git a/wrappers/_shared.nix b/wrappers/_shared.nix index 0aca2c6003..cb4b4971a4 100644 --- a/wrappers/_shared.nix +++ b/wrappers/_shared.nix @@ -3,7 +3,7 @@ filesOpt ? null, # Filepath prefix to apply to extraFiles filesPrefix ? "nvim/", - # Filepath to use when adding `cfg.initPath` to `filesOpt` + # Filepath to use when adding `cfg.finalConfig` to `filesOpt` # Is prefixed with `filesPrefix` initName ? "init.lua", }: @@ -59,7 +59,7 @@ in ) extraFiles ) // { - ${filesPrefix + initName}.source = cfg.initPath; + ${filesPrefix + initName}.source = cfg.finalConfig; } ) ) From 627ac908faacbaae8fd307efc5e0520103b62082 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Thu, 18 Jul 2024 13:35:01 +0100 Subject: [PATCH 3/9] modules/output: override `content` in top-level --- modules/output.nix | 4 ++-- modules/top-level/output.nix | 32 +++++++++++++++++++------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/modules/output.nix b/modules/output.nix index 2f403f19e6..c2c2707cbc 100644 --- a/modules/output.nix +++ b/modules/output.nix @@ -93,15 +93,15 @@ in content = mkOption { type = types.str; description = "The content of the config file"; - readOnly = true; visible = false; + # FIXME: can't be readOnly because we override it in top-level modules }; finalConfig = mkOption { type = types.package; description = "The config file written as a derivation"; + readOnly = true; internal = true; - # FIXME: can't be readOnly because we override it in top-level modules }; extraLuaPackages = mkOption { diff --git a/modules/top-level/output.nix b/modules/top-level/output.nix index 62adabe56b..e0059fb2f8 100644 --- a/modules/top-level/output.nix +++ b/modules/top-level/output.nix @@ -2,7 +2,6 @@ pkgs, config, lib, - helpers, ... }: with lib; @@ -106,17 +105,6 @@ with lib; } ); - customRC = - let - hasContent = str: (builtins.match "[[:space:]]*" str) == null; - in - (optionalString (hasContent neovimConfig.neovimRcContent) '' - vim.cmd([[ - ${neovimConfig.neovimRcContent} - ]]) - '') - + config.content; - extraWrapperArgs = builtins.concatStringsSep " " ( (optional (config.extraPackages != [ ]) ''--prefix PATH : "${makeBinPath config.extraPackages}"'') ++ (optional config.wrapRc ''--add-flags -u --add-flags "${config.finalConfig}"'') @@ -132,8 +120,26 @@ with lib; in { type = lib.mkForce "lua"; + + content = lib.mkForce ( + lib.concatStringsSep "\n" [ + (optionalString (hasContent neovimConfig.neovimRcContent) '' + vim.cmd([[ + ${neovimConfig.neovimRcContent} + ]]) + '') + config.extraConfigLuaPre + (optionalString (hasContent config.extraConfigVim) '' + vim.cmd([[ + ${config.extraConfigVim} + ]]) + '') + config.extraConfigLua + config.extraConfigLuaPost + ] + ); + finalPackage = wrappedNeovim; - finalConfig = lib.mkForce (helpers.writeLua config.target customRC); printInitPackage = pkgs.writeShellApplication { name = "nixvim-print-init"; From bf9aa0cf0ddca9703dbaa849404fc87b6c6ea70e Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Thu, 18 Jul 2024 13:35:48 +0100 Subject: [PATCH 4/9] modules/output: cleanup top-level General cleanup, in-lining and comments. --- modules/top-level/output.nix | 68 ++++++++++++------------------------ 1 file changed, 23 insertions(+), 45 deletions(-) diff --git a/modules/top-level/output.nix b/modules/top-level/output.nix index e0059fb2f8..30cb35fbde 100644 --- a/modules/top-level/output.nix +++ b/modules/top-level/output.nix @@ -69,54 +69,25 @@ with lib; config = let - defaultPlugin = { - plugin = null; - config = ""; - optional = false; + hasContent = str: (builtins.match "[[:space:]]*" str) == null; + + neovimConfig = pkgs.neovimUtils.makeNeovimConfig { + inherit (config) + extraPython3Packages + extraLuaPackages + viAlias + vimAlias + withRuby + withNodeJs + ; + plugins = config.extraPlugins; + # We handle `customRC` ourselves, to position it after `extraConfigLuaPre` }; - normalizedPlugins = map ( - x: defaultPlugin // (if x ? plugin then x else { plugin = x; }) - ) config.extraPlugins; - - neovimConfig = pkgs.neovimUtils.makeNeovimConfig ( - { - inherit (config) - extraPython3Packages - extraLuaPackages - viAlias - vimAlias - withRuby - withNodeJs - ; - # inherit customRC; - plugins = normalizedPlugins; - } - # Necessary to make sure the runtime path is set properly in NixOS 22.05, - # or more generally before the commit: - # cda1f8ae468 - neovim: pass packpath via the wrapper - // optionalAttrs (functionArgs pkgs.neovimUtils.makeNeovimConfig ? configure) { - configure.packages = { - nixvim = { - start = map (x: x.plugin) normalizedPlugins; - opt = [ ]; - }; - }; - } - ); - extraWrapperArgs = builtins.concatStringsSep " " ( (optional (config.extraPackages != [ ]) ''--prefix PATH : "${makeBinPath config.extraPackages}"'') ++ (optional config.wrapRc ''--add-flags -u --add-flags "${config.finalConfig}"'') ); - - wrappedNeovim = pkgs.wrapNeovimUnstable config.package ( - neovimConfig - // { - wrapperArgs = lib.escapeShellArgs neovimConfig.wrapperArgs + " " + extraWrapperArgs; - wrapRc = false; - } - ); in { type = lib.mkForce "lua"; @@ -139,7 +110,14 @@ with lib; ] ); - finalPackage = wrappedNeovim; + finalPackage = pkgs.wrapNeovimUnstable config.package ( + neovimConfig + // { + wrapperArgs = lib.escapeShellArgs neovimConfig.wrapperArgs + " " + extraWrapperArgs; + # We handle wrapRc ourselves so we can control how init.lua is written + wrapRc = false; + } + ); printInitPackage = pkgs.writeShellApplication { name = "nixvim-print-init"; @@ -149,13 +127,13 @@ with lib; ''; }; - extraConfigLuaPre = lib.optionalString config.wrapRc '' + extraConfigLuaPre = mkIf config.wrapRc '' -- Ignore the user lua configuration vim.opt.runtimepath:remove(vim.fn.stdpath('config')) -- ~/.config/nvim vim.opt.runtimepath:remove(vim.fn.stdpath('config') .. "/after") -- ~/.config/nvim/after vim.opt.runtimepath:remove(vim.fn.stdpath('data') .. "/site") -- ~/.local/share/nvim/site ''; - extraPlugins = if config.wrapRc then [ config.filesPlugin ] else [ ]; + extraPlugins = mkIf config.wrapRc [ config.filesPlugin ]; }; } From f50944ae78dcf8e0822b523578a3779db5365f8d Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Thu, 18 Jul 2024 14:13:33 +0100 Subject: [PATCH 5/9] modules/output: make `content` type `lines` This allows us to prefix the RC content built by `makeNeovimConfig`. --- modules/output.nix | 4 ++-- modules/top-level/output.nix | 22 ++++++---------------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/modules/output.nix b/modules/output.nix index c2c2707cbc..0a4fbda62b 100644 --- a/modules/output.nix +++ b/modules/output.nix @@ -91,10 +91,10 @@ in }; content = mkOption { - type = types.str; + type = types.lines; description = "The content of the config file"; visible = false; - # FIXME: can't be readOnly because we override it in top-level modules + # FIXME: can't be readOnly because we prefix it in top-level modules }; finalConfig = mkOption { diff --git a/modules/top-level/output.nix b/modules/top-level/output.nix index 30cb35fbde..c221179ac7 100644 --- a/modules/top-level/output.nix +++ b/modules/top-level/output.nix @@ -92,22 +92,12 @@ with lib; { type = lib.mkForce "lua"; - content = lib.mkForce ( - lib.concatStringsSep "\n" [ - (optionalString (hasContent neovimConfig.neovimRcContent) '' - vim.cmd([[ - ${neovimConfig.neovimRcContent} - ]]) - '') - config.extraConfigLuaPre - (optionalString (hasContent config.extraConfigVim) '' - vim.cmd([[ - ${config.extraConfigVim} - ]]) - '') - config.extraConfigLua - config.extraConfigLuaPost - ] + content = lib.mkIf (hasContent neovimConfig.neovimRcContent) ( + lib.mkBefore '' + vim.cmd([[ + ${neovimConfig.neovimRcContent} + ]]) + '' ); finalPackage = pkgs.wrapNeovimUnstable config.package ( From 3524eec8fb4ebaa9b4a8d85ef3e42d3a6d8d9e03 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Thu, 18 Jul 2024 14:16:08 +0100 Subject: [PATCH 6/9] lib/utils: move `hasContent` to helpers lib --- lib/utils.nix | 3 +++ modules/top-level/output.nix | 5 ++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/utils.nix b/lib/utils.nix index ae82ecac6a..bc16fa1288 100644 --- a/lib/utils.nix +++ b/lib/utils.nix @@ -5,6 +5,9 @@ }: with lib; { + # Whether a string contains something other than whitespace + hasContent = str: (builtins.match "[[:space:]]*" str) == null; + listToUnkeyedAttrs = list: builtins.listToAttrs (lib.lists.imap0 (idx: lib.nameValuePair "__unkeyed-${toString idx}") list); diff --git a/modules/top-level/output.nix b/modules/top-level/output.nix index c221179ac7..fd6c38927d 100644 --- a/modules/top-level/output.nix +++ b/modules/top-level/output.nix @@ -2,6 +2,7 @@ pkgs, config, lib, + helpers, ... }: with lib; @@ -69,8 +70,6 @@ with lib; config = let - hasContent = str: (builtins.match "[[:space:]]*" str) == null; - neovimConfig = pkgs.neovimUtils.makeNeovimConfig { inherit (config) extraPython3Packages @@ -92,7 +91,7 @@ with lib; { type = lib.mkForce "lua"; - content = lib.mkIf (hasContent neovimConfig.neovimRcContent) ( + content = lib.mkIf (helpers.hasContent neovimConfig.neovimRcContent) ( lib.mkBefore '' vim.cmd([[ ${neovimConfig.neovimRcContent} From 471e847fc680425b1592cb8bba171a6d7c3322c0 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Thu, 18 Jul 2024 14:26:22 +0100 Subject: [PATCH 7/9] modules/output: only print relevant parts of config --- modules/output.nix | 56 +++++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/modules/output.nix b/modules/output.nix index 0a4fbda62b..b76b9c718d 100644 --- a/modules/output.nix +++ b/modules/output.nix @@ -119,25 +119,45 @@ in writer = if config.type == "lua" then helpers.writeLua else pkgs.writeText; - contentLua = '' - ${config.extraConfigLuaPre} - vim.cmd([[ - ${config.extraConfigVim} - ]]) - ${config.extraConfigLua} - ${config.extraConfigLuaPost} - ''; + concatConfig = parts: lib.concatStringsSep "\n" (lib.filter helpers.hasContent parts); + + wrapConfig = + fn: parts: + let + s = concatConfig (toList parts); + in + optionalString (helpers.hasContent s) (fn s); + + contentLua = concatConfig [ + config.extraConfigLuaPre + (wrapConfig (s: '' + vim.cmd([[ + ${s} + ]]) + '') config.extraConfigVim) + config.extraConfigLua + config.extraConfigLuaPost + ]; - contentVim = '' - lua << EOF - ${config.extraConfigLuaPre} - EOF - ${config.extraConfigVim} - lua << EOF - ${config.extraConfigLua} - ${config.extraConfigLuaPost} - EOF - ''; + contentVim = concatConfig [ + (wrapConfig (s: '' + lua << EOF + ${s} + EOF + '') config.extraConfigLuaPre) + config.extraConfigVim + (wrapConfig + (s: '' + lua << EOF + ${s} + EOF + '') + [ + config.extraConfigLua + config.extraConfigLuaPost + ] + ) + ]; in { content = if config.type == "lua" then contentLua else contentVim; From a243253b6700735d8993d8741533aae2ae353b93 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Thu, 18 Jul 2024 15:21:27 +0100 Subject: [PATCH 8/9] modules/output: allow lua or vim init files --- modules/top-level/output.nix | 20 +++++++++++--------- wrappers/_shared.nix | 5 +---- wrappers/modules/nixos.nix | 1 + wrappers/nixos.nix | 1 - 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/modules/top-level/output.nix b/modules/top-level/output.nix index fd6c38927d..6c51e8d4f1 100644 --- a/modules/top-level/output.nix +++ b/modules/top-level/output.nix @@ -87,17 +87,19 @@ with lib; (optional (config.extraPackages != [ ]) ''--prefix PATH : "${makeBinPath config.extraPackages}"'') ++ (optional config.wrapRc ''--add-flags -u --add-flags "${config.finalConfig}"'') ); + + configPrefix = + if config.type == "lua" then + '' + vim.cmd([[ + ${neovimConfig.neovimRcContent} + ]]) + '' + else + neovimConfig.neovimRcContent; in { - type = lib.mkForce "lua"; - - content = lib.mkIf (helpers.hasContent neovimConfig.neovimRcContent) ( - lib.mkBefore '' - vim.cmd([[ - ${neovimConfig.neovimRcContent} - ]]) - '' - ); + content = lib.mkIf (helpers.hasContent neovimConfig.neovimRcContent) (lib.mkBefore configPrefix); finalPackage = pkgs.wrapNeovimUnstable config.package ( neovimConfig diff --git a/wrappers/_shared.nix b/wrappers/_shared.nix index cb4b4971a4..d9a6577eb0 100644 --- a/wrappers/_shared.nix +++ b/wrappers/_shared.nix @@ -3,9 +3,6 @@ filesOpt ? null, # Filepath prefix to apply to extraFiles filesPrefix ? "nvim/", - # Filepath to use when adding `cfg.finalConfig` to `filesOpt` - # Is prefixed with `filesPrefix` - initName ? "init.lua", }: { pkgs, @@ -59,7 +56,7 @@ in ) extraFiles ) // { - ${filesPrefix + initName}.source = cfg.finalConfig; + ${filesPrefix + cfg.target}.source = cfg.finalConfig; } ) ) diff --git a/wrappers/modules/nixos.nix b/wrappers/modules/nixos.nix index b65e5d73e9..8ae92c2f92 100644 --- a/wrappers/modules/nixos.nix +++ b/wrappers/modules/nixos.nix @@ -8,5 +8,6 @@ config = { wrapRc = lib.mkForce true; + target = lib.mkDefault "sysinit.lua"; }; } diff --git a/wrappers/nixos.nix b/wrappers/nixos.nix index 7ffe29cde1..630c80a57b 100644 --- a/wrappers/nixos.nix +++ b/wrappers/nixos.nix @@ -42,7 +42,6 @@ in "environment" "etc" ]; - initName = "sysinit.lua"; }) ]; From a90a58e36ee60891e34c94f36672eeeec6c1163e Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Thu, 18 Jul 2024 15:23:29 +0100 Subject: [PATCH 9/9] modules/output: make `type` option readOnly This is a breaking change, but IMO it makes more sense to configure this via the `target` filename. Either `target` or `type` should be readonly otherwise we would want circular defaults. --- modules/output.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/output.nix b/modules/output.nix index b76b9c718d..39cd78c0ed 100644 --- a/modules/output.nix +++ b/modules/output.nix @@ -82,6 +82,7 @@ in default = if lib.hasSuffix ".vim" config.target then "vim" else "lua"; defaultText = lib.literalMD ''`"lua"` unless `config.target` ends with `".vim"`''; description = "Whether the generated file is a vim or a lua file"; + readOnly = true; }; target = mkOption {