{ lib, nixvimOptions, }: with lib; { mkVimPlugin = config: { name, description ? null, package ? null, extraPlugins ? [], extraPackages ? [], options ? {}, globalPrefix ? "", addExtraConfigRenameWarning ? false, ... }: let cfg = config.plugins.${name}; # TODO support nested options! pluginOptions = mapAttrs ( optName: opt: opt.option ) options; globals = mapAttrs' (optName: opt: { name = let optGlobal = if opt.global == null then optName else opt.global; in globalPrefix + optGlobal; value = cfg.${optName}; }) options; # does this evaluate package? packageOption = if package == null then {} else { package = nixvimOptions.mkPackageOption name package; }; createSettingsOption = (isString globalPrefix) && (globalPrefix != ""); extraConfigOption = optionalAttrs createSettingsOption { settings = mkOption { type = with types; attrsOf anything; description = '' The configuration options for ${name} without the '${globalPrefix}' prefix. Example: To set '${globalPrefix}_foo_bar' to 1, write ```nix extraConfig = { foo_bar = true; }; ``` ''; default = {}; }; }; in { options.plugins.${name} = { enable = mkEnableOption ( if description == null then name else description ); } // extraConfigOption // packageOption // pluginOptions; imports = optional (addExtraConfigRenameWarning && createSettingsOption) ( mkRenamedOptionModule ["plugins" name "extraConfig"] ["plugins" name "settings"] ); config = mkIf cfg.enable { inherit extraPackages globals; # does this evaluate package? it would not be desired to evaluate pacakge if we use another package. extraPlugins = extraPlugins ++ optional (package != null) cfg.package; }; }; mkDefaultOpt = { type, global ? null, description ? null, example ? null, default ? null, ... }: { option = mkOption { type = types.nullOr type; inherit default description example; }; inherit global; }; }