diff --git a/lib/utils.nix b/lib/utils.nix index ae82ecac..3f58ec62 100644 --- a/lib/utils.nix +++ b/lib/utils.nix @@ -4,7 +4,14 @@ _nixvimTests, }: with lib; -{ +rec { + # Whether a string contains something other than whitespaces + hasContent = str: builtins.match "[[:space:]]*" str == null; + + # Concatenate a list of strings, adding a newline at the end of each one, + # but skipping strings containing only whitespace characters + concatNonEmptyLines = lines: concatLines (builtins.filter hasContent lines); + listToUnkeyedAttrs = list: builtins.listToAttrs (lib.lists.imap0 (idx: lib.nameValuePair "__unkeyed-${toString idx}") list); @@ -118,4 +125,26 @@ with lib; ${string} end ''; + + # Wrap Vimscript for using in lua, + # but only if the string contains something other than whitespaces + # TODO: account for a possible ']]' in the string + wrapVimscriptForLua = + string: + optionalString (hasContent string) '' + vim.cmd([[ + ${string} + ]]) + ''; + + # Wrap lua script for using in Vimscript, + # but only if the string contains something other than whitespaces + # TODO: account for a possible 'EOF' if the string + wrapLuaForVimscript = + string: + optionalString (hasContent string) '' + lua << EOF + ${string} + EOF + ''; } diff --git a/modules/output.nix b/modules/output.nix index 0cfdd5b7..0beb31d4 100644 --- a/modules/output.nix +++ b/modules/output.nix @@ -1,4 +1,9 @@ -{ lib, config, ... }: +{ + lib, + config, + helpers, + ... +}: with lib; let pluginWithConfigType = types.submodule { @@ -97,29 +102,27 @@ in }; }; - config = - let - contentLua = '' - ${config.extraConfigLuaPre} - vim.cmd([[ - ${config.extraConfigVim} - ]]) - ${config.extraConfigLua} - ${config.extraConfigLuaPost} - ''; - - contentVim = '' - lua << EOF - ${config.extraConfigLuaPre} - EOF - ${config.extraConfigVim} - lua << EOF - ${config.extraConfigLua} - ${config.extraConfigLuaPost} - EOF - ''; - in - { - content = if config.type == "lua" then contentLua else contentVim; - }; + config = { + content = + if config.type == "lua" then + # Lua + helpers.concatNonEmptyLines [ + config.extraConfigLuaPre + (helpers.wrapVimscriptForLua config.extraConfigVim) + config.extraConfigLua + config.extraConfigLuaPost + ] + else + # Vimscript + helpers.concatNonEmptyLines [ + (helpers.wrapLuaForVimscript config.extraConfigLuaPre) + config.extraConfigVim + (helpers.wrapLuaForVimscript ( + helpers.concatNonEmptyLines [ + config.extraConfigLua + config.extraConfigLuaPost + ] + )) + ]; + }; } diff --git a/modules/top-level/output.nix b/modules/top-level/output.nix index 268316fc..57b21523 100644 --- a/modules/top-level/output.nix +++ b/modules/top-level/output.nix @@ -107,16 +107,10 @@ with lib; } ); - customRC = - let - hasContent = str: (builtins.match "[[:space:]]*" str) == null; - in - (optionalString (hasContent neovimConfig.neovimRcContent) '' - vim.cmd([[ - ${neovimConfig.neovimRcContent} - ]]) - '') - + config.content; + customRC = helpers.concatNonEmptyLines [ + (helpers.wrapVimscriptForLua neovimConfig.neovimRcContent) + config.content + ]; init = helpers.writeLua "init.lua" customRC; diff --git a/tests/test-sources/modules/output.nix b/tests/test-sources/modules/output.nix index 143b8bd4..74d7bd09 100644 --- a/tests/test-sources/modules/output.nix +++ b/tests/test-sources/modules/output.nix @@ -4,4 +4,90 @@ # Make sure jsregexp is in LUA_PATH extraConfigLua = ''require("jsregexp")''; }; + + # Test that all extraConfigs are present in output + all-configs.module = + { + config, + pkgs, + lib, + ... + }: + let + configs = { + extraConfigLuaPre = "string.format('extraConfigLuaPre1')"; + extraConfigLua = "string.format('extraConfigLua2')"; + extraConfigLuaPost = "string.format('extraConfigLuaPost3')"; + extraConfigVim = "let g:var = 'extraConfigVim4'"; + }; + mkConfigAssertions = name: value: [ + { + assertion = lib.hasInfix "extraConfigLuaPre1" value; + message = "Configuration file ${name} does not contain extraConfigLuaPre."; + } + { + assertion = lib.hasInfix "extraConfigLua2" value; + message = "Configuration file ${name} does not contain extraConfigLua."; + } + { + assertion = lib.hasInfix "extraConfigLuaPost3" value; + message = "Configuration file ${name} does not contain extraConfigLuaPost."; + } + { + assertion = lib.hasInfix "extraConfigVim4" value; + message = "Configuration file ${name} does not contain extraConfigVim."; + } + ]; + in + configs + // { + files = { + "test.lua" = configs; + "test.vim" = configs; + }; + + # Plugin configs + extraPlugins = [ + { + plugin = pkgs.emptyDirectory; + config = "let g:var = 'neovimRcContent5'"; + } + ]; + + assertions = + mkConfigAssertions "init.lua" config.content + ++ mkConfigAssertions "test.lua" config.files."test.lua".content + ++ mkConfigAssertions "test.vim" config.files."test.vim".content + # Check the final generated init.lua too + ++ mkConfigAssertions "initPath" (builtins.readFile config.initPath) + ++ [ + # Only init.lua contains configuration from plugin definitions + { + assertion = lib.hasInfix "neovimRcContent5" (builtins.readFile config.initPath); + message = "Configuration file init.lua does not contain plugin configs"; + } + ]; + }; + + files-default-empty.module = + { config, helpers, ... }: + { + files = { + # lua type + "test.lua" = { }; + # vim type + "test.vim" = { }; + }; + + assertions = [ + { + assertion = !helpers.hasContent config.files."test.lua".content; + message = "Default content of test.lua file is expected to be empty."; + } + { + assertion = !helpers.hasContent config.files."test.vim".content; + message = "Default content of test.vim file is expected to be empty."; + } + ]; + }; }