diff --git a/pkgs/applications/editors/neovim/module.nix b/pkgs/applications/editors/neovim/module.nix new file mode 100644 index 000000000000..41b56b81113d --- /dev/null +++ b/pkgs/applications/editors/neovim/module.nix @@ -0,0 +1,115 @@ +{ config, lib, ... }: +let + /* + transform all plugins into an attrset + { optional = bool; plugin = package; } + */ + normalizePlugins = + plugins: + let + defaultPlugin = { + plugin = null; + config = null; + optional = false; + }; + in + map (x: defaultPlugin // (if (x ? plugin) then x else { plugin = x; })) plugins; + + pluginWithConfigType = + with lib; + types.submodule { + options = { + config = mkOption { + type = types.nullOr types.lines; + description = "viml configuration associated with this plugin."; + default = null; + example = "set title"; + }; + + optional = mkEnableOption "optional" // { + description = "Don't load automatically on startup (load with :packadd)"; + }; + + plugin = mkOption { + type = types.package; + example = lib.literalExpression "vimPlugins.vim-fugitive"; + description = "vim plugin"; + }; + }; + }; + +in +{ + options = { + plugins = lib.mkOption { + type = with lib.types; listOf (either package pluginWithConfigType); + default = [ ]; + apply = normalizePlugins; + example = lib.literalExpression '' + with pkgs.vimPlugins; [ + yankring + vim-nix + { plugin = vim-startify; + config = "let g:startify_change_to_vcs_root = 0"; + } + ] + ''; + description = '' + List of vim plugins to install optionally associated with + configuration to be placed in init.vim. + ''; + }; + + runtimeDeps = lib.mkOption { + readOnly = true; + type = with lib.types; listOf package; + description = '' + List of derivations required at runtime + ''; + }; + + pluginAdvisedLua = lib.mkOption { + readOnly = true; + type = lib.types.listOf lib.types.lines; + description = '' + Recommended configuration set in vim plugins via ".passthru.initLua". + ''; + }; + + userPluginViml = lib.mkOption { + readOnly = true; + type = lib.types.listOf (lib.types.lines); + description = '' + The viml config set by the user. + ''; + }; + + }; + + config = + let + pluginsNormalized = normalizePlugins config.plugins; + in + { + pluginAdvisedLua = + let + op = + acc: normalizedPlugin: + acc + ++ lib.optional ( + normalizedPlugin.plugin.passthru ? initLua + ) normalizedPlugin.plugin.passthru.initLua; + in + lib.foldl' op [ ] pluginsNormalized; + + runtimeDeps = + let + op = acc: normalizedPlugin: acc ++ normalizedPlugin.plugin.runtimeDeps or [ ]; + in + lib.foldl' op [ ] pluginsNormalized; + + userPluginViml = lib.foldl ( + acc: p: if p.config != null then acc ++ [ p.config ] else acc + ) [ ] pluginsNormalized; + }; +} diff --git a/pkgs/applications/editors/neovim/utils.nix b/pkgs/applications/editors/neovim/utils.nix index 23968bf21d0e..a358b96a3ba2 100644 --- a/pkgs/applications/editors/neovim/utils.nix +++ b/pkgs/applications/editors/neovim/utils.nix @@ -79,25 +79,30 @@ let plugins: let + neovimConfig = + structuredConfigure: + let + module = import ./module.nix; + # Generate init.vim configuration + cfg = ( + lib.evalModules { + modules = [ + module + structuredConfigure + ]; + } + ); + in + cfg.config; + + checked_cfg = neovimConfig { + inherit plugins; + }; + pluginsNormalized = normalizePlugins plugins; vimPackage = normalizedPluginsToVimPackage pluginsNormalized; - userPluginViml = lib.foldl ( - acc: p: if p.config != null then acc ++ [ p.config ] else acc - ) [ ] pluginsNormalized; - - pluginAdvisedLua = - let - op = - acc: normalizedPlugin: - acc - ++ lib.optional ( - normalizedPlugin.plugin.passthru ? initLua - ) normalizedPlugin.plugin.passthru.initLua; - in - lib.foldl' op [ ] pluginsNormalized; - getDeps = attrname: map (plugin: plugin.${attrname} or (_: [ ])); requiredPlugins = vimUtils.requiredPluginsForPackage vimPackage; @@ -108,10 +113,11 @@ let inherit pluginPython3Packages; # viml config set by the user along with the plugin - inherit userPluginViml; - - # recommended configuration set in vim plugins ".passthru.initLua" - inherit pluginAdvisedLua; + inherit (checked_cfg) + userPluginViml + runtimeDeps + pluginAdvisedLua + ; # A Vim "package", see ':h packages' # You most likely want to use vimPackage as follows: @@ -119,12 +125,6 @@ let # finalPackdir = neovimUtils.packDir packpathDirs; inherit vimPackage; - runtimeDeps = - let - op = acc: normalizedPlugin: acc ++ normalizedPlugin.plugin.runtimeDeps or [ ]; - in - lib.foldl' op [ ] pluginsNormalized; - }; /*