Skip to content

docs/hacking: add notes about listOf default priority #885

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/manual/hacking.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ hacking/guidelines.md
hacking/testing.md
hacking/keybinds.md
hacking/additional-plugins.md
hacking/default-value-priority.md
```
92 changes: 92 additions & 0 deletions docs/manual/hacking/default-value-priority.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Default value priority in `listOf` and `attrsOf` options {#sec-listOf-attrsOf-priority}

When defining options of type `listOf` and `attrsOf`, you should pay close
attention to how the default value is defined.

## Default values that should be extended {#ch-extended-defaults}

In most cases, you want user configuration to "extend" your default value, in
this case, your "default" value should be defined using normal priority, i.e. in
a `config` block:

```nix
{lib, ...}: let
inherit (lib.types) listOf str;
inherit (lib.options) literalExpression;
in {
options = {
vim.telescope.setupOpts.file_ignore_patterns = mkOption {
type = listOf str;
# provide a useful defaultText so users are aware of defaults
defaultText = literalExpression ''
["node_modules" "%.git/" "dist/" "build/" "target/" "result/"];
'';
};
};
}
```

This way, when users specify:

```nix
config.vim.telescope.setupOpts.file_ignore_patterns = [".vscode/"];
```

The final value is
`["node_modules" "%.git/" "dist/" "build/" "target/" "result/" ".vscode/"]`.

::: {.note}

Users can still get rid of the default value by assigning a `mkForce` value to
the option:

```nix
{lib, ...}: {
config.vim.telescope.setupOpts.file_ignore_patterns = lib.mkForce [];
}
```

:::

## Default values that should be overridden {#ch-overridden-defaults}

In some cases, it makes sense to let any user value "override" your default, in
these cases, you should assign default values using default priority, i.e. using
the `default` key of `mkOption`:

```nix
{lib, ...}: let
inherit (lib.types) listOf str;
inherit (lib.options) mkOption;
in {
vim.telescope.setupOpts.pickers.find_files.find_command = mkOption {
description = "cmd to use for finding files";
type = listOf str;
default = ["${pkgs.fd}/bin/fd" "--type=file"];
}
}
```

This way, when users specify:

```nix
{
config.vim.telescope.setupOpts.pickers.find_files.find_command = [
"fd"
"--type=file"
"--some-other-option"
];
}
```

The final value of the option is `["fd" "--type=file" "--some-other-option"]`.

Users can still choose to "extend" our default value by using `mkDefault`,
possibly with `mkAfter`/`mkBefore`:

```nix
{lib, ...}: {
config.vim.telescope.setupOpts.pickers.find_files.find_command =
lib.mkDefault (lib.mkBefore ["--max-depth=10"]);
}
```
Loading