{ lib, pkgs, ... }: let pluginOpts = ({ name, config, ... }: { options = with lib; with types; { name = mkOption { type = str; }; extraImports = mkOption { type = attrsOf str; default = { }; example = { hint = "hop.hint"; }; }; varName = mkOption { type = str; # TODO: add validation }; package = mkPackageOption pkgs.vimPlugins name { }; isDependency = mkOption { type = bool; default = false; }; beforeSetup = mkOption { type = listOf attrs; default = [ ]; }; setupFnName = mkOption { type = str; default = "setup"; }; setupSettings = mkOption { type = nullOr attrs; default = null; }; afterSetup = mkOption { type = listOf attrs; default = [ ]; }; extra = mkOption { type = listOf attrs; default = [ ]; }; genConfig = mkOption { type = listOf attrs; readOnly = true; internal = true; }; luaConfig = mkOption { type = str; readOnly = true; internal = true; }; }; config = { name = lib.mkDefault name; varName = lib.mkDefault (builtins.replaceStrings [ "-" "/" ] [ "_" "_" ] config.name); genConfig = with lib.nix2lua; lib.mkIf (!config.isDependency) (lib.flatten [ (local (set config.varName (require config.name))) (lib.mapAttrsToList (k: v: local (set k) (require v)) config.extraImports) config.beforeSetup (lib.optional (config.setupSettings != null) (pipe1 (var config.varName) (call config.setupFnName config.setupSettings)) ) config.afterSetup config.extra ]); luaConfig = with lib.nix2lua; toLua (spaceBetween config.genConfig); }; }); in { options.plugin = with lib; with types; mkOption { type = attrsOf (submodule pluginOpts); default = { }; }; }