{ lib, helpers, config, pkgs, ... }: with lib; let cfg = config.plugins.packer; in { options = { plugins.packer = { enable = mkEnableOption "packer.nvim"; plugins = with types; let pluginType = either str (submodule { options = { name = mkOption { type = str; description = "Name of the plugin to install"; }; disable = helpers.mkNullOrOption bool "Mark plugin as inactive"; as = helpers.mkNullOrOption str "Specifies an alias under which to install the plugin"; installer = helpers.mkNullOrOption str "A custom installer"; updater = helpers.mkNullOrOption str "A custom updater"; after = helpers.mkNullOrOption (either str (listOf str)) "Plugins to load after this plugin"; rtp = helpers.mkNullOrOption str "Specifies a subdirectory of the plugin to add to runtimepath"; opt = helpers.mkNullOrOption bool "Marks a plugin as optional"; branch = helpers.mkNullOrOption str "Git branch to use"; tag = helpers.mkNullOrOption str "Git tag to use"; commit = helpers.mkNullOrOption str "Git commit to use"; lock = helpers.mkNullOrOption bool "Skip this plugin in updates"; run = helpers.mkNullOrOption (oneOf [ str helpers.rawType (listOf (either str helpers.rawType)) ]) "Post-install hook"; requires = helpers.mkNullOrOption (either str listOfPlugins) "Plugin dependencies"; rocks = helpers.mkNullOrOption (either str (listOf (either str attrs))) "Luarocks dependencies"; config = helpers.mkNullOrOption (either str helpers.rawType) "Code to run after this plugin is loaded"; setup = helpers.mkNullOrOption (either str helpers.rawType) "Code to be run before this plugin is loaded"; cmd = helpers.mkNullOrOption (either str (listOf str)) "Commands which load this plugin"; ft = helpers.mkNullOrOption (either str (listOf str)) "Filetypes which load this plugin"; keys = helpers.mkNullOrOption (either str (listOf str)) "Keymaps which load this plugin"; event = helpers.mkNullOrOption (either str (listOf str)) "Autocommand events which load this plugin"; fn = helpers.mkNullOrOption (either str (listOf str)) "Functions which load this plugin"; cond = helpers.mkNullOrOption (oneOf [ str helpers.rawType (listOf (either str helpers.rawType)) ]) "Conditional test to load this plugin"; module = helpers.mkNullOrOption (either str (listOf str)) "Patterns of module names which load this plugin"; }; }); listOfPlugins = types.listOf pluginType; in mkOption { type = listOfPlugins; default = []; description = "List of plugins"; }; rockPlugins = mkOption { type = with types; listOf (either str attrs); description = "List of lua rock plugins"; default = []; example = '' [ "penlight" "lua-resty-http" "lpeg" ] ''; }; }; }; config = mkIf cfg.enable { extraPlugins = [(pkgs.vimPlugins.packer-nvim.overrideAttrs (_: {pname = "packer.nvim";}))]; extraPackages = [pkgs.git]; extraConfigLua = let luaRockPluginToLua = luaRockPlugin: if isAttrs luaRockPlugin then mapAttrs' (k: v: { name = if k == "name" then "__unkeyed" else k; value = v; }) luaRockPlugin else luaRockPlugin; luaRockListToLua = map luaRockPluginToLua; pluginToLua = plugin: if isAttrs plugin then { "__unkeyed" = plugin.name; inherit (plugin) disable as; installer = helpers.mkRaw plugin.installer; updater = helpers.mkRaw plugin.updater; inherit (plugin) after rtp opt branch tag commit lock run ; requires = helpers.ifNonNull' plugin.requires ( if isList plugin.requires then (pluginListToLua plugin.requires) else plugin.requires ); rocks = helpers.ifNonNull' plugin.rocks ( if isList plugin.rocks then luaRockListToLua plugin.rocks else plugin.rocks ); inherit (plugin) config setup cmd ft keys event fn cond module ; } else plugin; pluginListToLua = map pluginToLua; plugins = pluginListToLua cfg.plugins; packedPlugins = if length plugins == 1 then head plugins else plugins; luaRockPlugins = luaRockListToLua cfg.rockPlugins; luaRocksString = optionalString (cfg.rockPlugins != []) "use_rocks ${helpers.toLuaObject luaRockPlugins}"; in mkIf (cfg.plugins != []) '' require('packer').startup(function() use ${helpers.toLuaObject packedPlugins} ${luaRocksString} end) ''; }; }