diff --git a/lib/options.nix b/lib/options.nix index 07cc9feff0..6e8d5cd965 100644 --- a/lib/options.nix +++ b/lib/options.nix @@ -7,75 +7,116 @@ with lib; with nixvimUtils; rec { # Creates an option with a nullable type that defaults to null. - mkNullOrOption = - type: desc: - lib.mkOption { - type = lib.types.nullOr type; - default = null; - description = desc; - }; + mkNullOrOption' = + { + type, + default ? null, + ... + }@args: + lib.mkOption ( + args + // { + type = lib.types.nullOr type; + inherit default; + } + ); + mkNullOrOption = type: description: mkNullOrOption' { inherit type description; }; - mkCompositeOption = desc: options: mkNullOrOption (types.submodule { inherit options; }) desc; + mkCompositeOption' = + { options, ... }@args: + mkNullOrOption' ( + (filterAttrs (n: _: n != "options") args) // { type = types.submodule { inherit options; }; } + ); + mkCompositeOption = description: options: mkCompositeOption' { inherit description options; }; - mkNullOrStr = mkNullOrOption (with nixvimTypes; maybeRaw str); + mkNullOrStr' = args: mkNullOrOption' (args // { type = with nixvimTypes; maybeRaw str; }); + mkNullOrStr = description: mkNullOrStr' { inherit description; }; - mkNullOrLua = - desc: - lib.mkOption { - type = lib.types.nullOr nixvimTypes.strLua; - default = null; - description = desc; - apply = mkRaw; - }; + mkNullOrLua' = + args: + mkNullOrOption' ( + args + // { + type = nixvimTypes.strLua; + apply = mkRaw; + } + ); + mkNullOrLua = description: mkNullOrLua' { inherit description; }; - mkNullOrLuaFn = - desc: - lib.mkOption { - type = lib.types.nullOr nixvimTypes.strLuaFn; - default = null; - description = desc; - apply = mkRaw; - }; + mkNullOrLuaFn' = + args: + mkNullOrOption' ( + args + // { + type = nixvimTypes.strLuaFn; + apply = mkRaw; + } + ); + mkNullOrLuaFn = description: mkNullOrLua' { inherit description; }; - mkNullOrStrLuaOr = - ty: desc: - lib.mkOption { - type = lib.types.nullOr (types.either nixvimTypes.strLua ty); - default = null; - description = desc; - apply = v: if builtins.isString v then mkRaw v else v; - }; + mkNullOrStrLuaOr' = + { type, ... }@args: + mkNullOrOption' ( + args + // { + type = with nixvimTypes; either strLua type; + apply = v: if isString v then mkRaw v else v; + } + ); + mkNullOrStrLuaOr = type: description: mkNullOrStrLuaOr' { inherit type description; }; - mkNullOrStrLuaFnOr = - ty: desc: - lib.mkOption { - type = lib.types.nullOr (types.either nixvimTypes.strLuaFn ty); - default = null; - description = desc; - apply = v: if builtins.isString v then mkRaw v else v; - }; + mkNullOrStrLuaFnOr' = + { type, ... }@args: + mkNullOrOption' ( + args + // { + type = with nixvimTypes; either strLuaFn type; + apply = v: if isString v then mkRaw v else v; + } + ); + mkNullOrStrLuaFnOr = type: description: mkNullOrStrLuaFnOr' { inherit type description; }; defaultNullOpts = rec { - # Description helpers - mkDefaultDesc = - defaultValue: - let - default = - # Assume a string default is already formatted as intended, - # historically strings were the only type accepted here. - # TODO consider deprecating this behavior so we can properly quote strings - if isString defaultValue then defaultValue else generators.toPretty { } defaultValue; - in - "Plugin default:" - + ( - # Detect whether `default` is multiline or inline: - if hasInfix "\n" default then "\n\n```nix\n${default}\n```" else " `${default}`" - ); + /** + Build a description with a plugin default. + + The [default] can be any value, and it will be formatted using `lib.generators.toPretty`. + + If [default] is a String, it will not be formatted. + This behavior will likely change in the future. + + # Example + ```nix + mkDesc 1 "foo" + => '' + foo + + Plugin default: `1` + '' + ``` + + # Type + ``` + mkDesc :: Any -> String -> String + ``` + # Arguments + - [default] The plugin's default + - [desc] The option's description + */ mkDesc = default: desc: let - defaultDesc = mkDefaultDesc default; + # Assume a string default is already formatted as intended, + # historically strings were the only type accepted here. + # TODO deprecate this behavior so we can properly quote strings + defaultString = if isString default then default else generators.toPretty { } default; + defaultDesc = + "Plugin default:" + + ( + # Detect whether `default` is multiline or inline: + if hasInfix "\n" defaultString then "\n\n```nix\n${defaultString}\n```" else " `${defaultString}`" + ); in if desc == "" then defaultDesc @@ -86,11 +127,24 @@ rec { ${defaultDesc} ''; + mkNullable' = + { default, description, ... }@args: + mkNullOrOption' ( + args + // { + default = null; + description = mkDesc default description; + } + ); mkNullable = - type: default: desc: - mkNullOrOption type (mkDesc default desc); + type: default: description: + mkNullable' { inherit type default description; }; - mkNullableWithRaw = type: mkNullable (nixvimTypes.maybeRaw type); + mkNullableWithRaw' = + { type, ... }@args: mkNullable' (args // { type = nixvimTypes.maybeRaw type; }); + mkNullableWithRaw = + type: default: description: + mkNullableWithRaw' { inherit type default description; }; mkStrLuaOr = type: default: desc: @@ -117,9 +171,22 @@ rec { default: assert default == null || isString default; mkNullableWithRaw types.str (generators.toPretty { } default); - mkAttributeSet = mkNullable nixvimTypes.attrs; - mkListOf = ty: default: mkNullable (with nixvimTypes; listOf (maybeRaw ty)) default; - mkAttrsOf = ty: default: mkNullable (with nixvimTypes; attrsOf (maybeRaw ty)) default; + + mkAttributeSet' = args: mkNullable' (args // { type = nixvimTypes.attrs; }); + mkAttributeSet = default: description: mkAttributeSet' { inherit default description; }; + + mkListOf' = + { type, ... }@args: mkNullable' (args // { type = with nixvimTypes; listOf (maybeRaw type); }); + mkListOf = + type: default: description: + mkListOf' { inherit type default description; }; + + mkAttrsOf' = + { type, ... }@args: mkNullable' (args // { type = with nixvimTypes; attrsOf (maybeRaw type); }); + mkAttrsOf = + type: default: description: + mkAttrsOf' { inherit type default description; }; + mkEnum = enumValues: default: mkNullableWithRaw (types.enum enumValues) ( @@ -181,23 +248,25 @@ rec { mkPackageOption = { - name ? null, # Can be null if a custom description is given. - default, + name ? null, # Can be omitted if a custom description is given. description ? null, - example ? null, - }: - mkOption { - type = with types; nullOr package; - inherit default example; - description = - if description == null then - '' - Which package to use for `${name}`. - Set to `null` to disable its automatic installation. - '' - else - description; - }; + default, # `default` is not optional + ... + }@args: + mkNullOrOption' ( + (filterAttrs (n: _: n != "name") args) + // { + type = types.package; + description = + if description == null then + '' + Which package to use for `${name}`. + Set to `null` to disable its automatic installation. + '' + else + description; + } + ); mkPluginPackageOption = name: default: