lib/options: move "plugin default" into defaultText

Introduce a new `helpers.pluginDefaultText` and deprecate `helpers.defaultNullOpts.mkDesc`.

Displaying the "plugin default" within `defaultText` ensures that both
defaults are grouped together in the docs.

Also take the first step towards transitioning `defaultNullOpts` from
using `default` to `pluginDefault` to mean "plugin default".
This commit is contained in:
Matt Sturgeon 2024-06-10 03:23:17 +01:00
parent 8a462dc957
commit 33a32c9417
No known key found for this signature in database
GPG key ID: 4F91844CED1A8299

View file

@ -6,6 +6,65 @@
with lib; with lib;
with nixvimUtils; with nixvimUtils;
rec { rec {
# Render a plugin default string
pluginDefaultText =
let
# Assume a string `default` is already formatted as intended,
# TODO: remove this behavior so we can quote strings properly
# historically strings were the only type accepted by mkDesc.
legacyRenderOptionValue =
v:
literalExpression (
if isString v then
v
else
generators.toPretty {
allowPrettyValues = true;
multiline = true;
} v
);
in
{
# plugin default: any value or literal expression
pluginDefault,
# nix option default value, used if `nixDefaultText` is missing
default ? null,
# nix option default string or literal expression
defaultText ? (options.renderOptionValue default) // {
__lang = "nix";
},
...
}:
let
# Only add `__lang` if `pluginDefault` is not already a literal type
pluginDefaultText =
if pluginDefault ? _type && pluginDefault ? text then
pluginDefault
else
(legacyRenderOptionValue pluginDefault) // { __lang = "nix"; };
# Format text using markdown code block or inline code
# Handle `v` being a literalExpression or literalMD type
toMD =
v:
let
value = options.renderOptionValue v;
multiline = hasInfix "\n" value.text;
lang = value.__lang or ""; # `__lang` is added internally when parsed in argument defaults
in
if value._type == "literalMD" then
if multiline then "\n${value.text}" else " ${value.text}"
else if multiline then
"\n```${lang}\n${value.text}\n```"
else
" `${value.text}`";
in
literalMD ''
${toMD defaultText}
_Plugin default:_${toMD pluginDefaultText}
'';
# Creates an option with a nullable type that defaults to null. # Creates an option with a nullable type that defaults to null.
mkNullOrOption' = mkNullOrOption' =
{ {
@ -79,55 +138,39 @@ rec {
defaultNullOpts = defaultNullOpts =
let let
# Convert `defaultNullOpts`-style arguments into normal `mkOption`-style arguments, # Convert `defaultNullOpts`-style arguments into normal `mkOption`-style arguments,
# i.e. moves `default` into `description` using `defaultNullOpts.mkDesc` # i.e. merge `default` or `defaultText` into `defaultText`.
# #
# "Plugin default" is only added if `args` has a `default` attribute # "Plugin default" is only added if `args` has either a `default` or `defaultText` attribute.
convertArgs = convertArgs =
args: args:
( (
args # TODO filter pluginDefault
(filterAttrs (
n: _:
!(elem n [
"pluginDefault"
"defaultText"
])
) args)
// { // {
# TODO assert that args didn't attempt to set `default` or `defaultText`
default = null; default = null;
} }
// (optionalAttrs (args ? default) { // (optionalAttrs (args ? pluginDefault || args ? default || args ? defaultText) {
description = defaultNullOpts.mkDesc args.default (args.description or ""); defaultText = pluginDefaultText {
# TODO: this is here for backwards compatibility:
# once `defaultNullOpts` migrates from `default` to `pluginDefault`
# then we can pass in `args` unmodified or simply inherit `pluginDefault`
pluginDefault = args.pluginDefault or args.defaultText or args.default;
};
}) })
); );
in in
rec { rec {
/** # TODO: deprecated in favor of `helpers.pluginDefaultText`
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 = mkDesc =
default: desc: default: desc:
let let
# 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; defaultString = if isString default then default else generators.toPretty { } default;
defaultDesc = defaultDesc =
"_Plugin default:_" "_Plugin default:_"