diff --git a/nixos/doc/manual/development/option-types.section.md b/nixos/doc/manual/development/option-types.section.md
new file mode 100644
index 000000000000..ed557206659f
--- /dev/null
+++ b/nixos/doc/manual/development/option-types.section.md
@@ -0,0 +1,558 @@
+# Options Types {#sec-option-types}
+
+Option types are a way to put constraints on the values a module option
+can take. Types are also responsible of how values are merged in case of
+multiple value definitions.
+
+## Basic Types {#sec-option-types-basic}
+
+Basic types are the simplest available types in the module system. Basic
+types include multiple string types that mainly differ in how definition
+merging is handled.
+
+`types.bool`
+
+: A boolean, its values can be `true` or `false`.
+
+`types.path`
+
+: A filesystem path, defined as anything that when coerced to a string
+ starts with a slash. Even if derivations can be considered as path,
+ the more specific `types.package` should be preferred.
+
+`types.package`
+
+: A derivation or a store path.
+
+`types.anything`
+
+: A type that accepts any value and recursively merges attribute sets
+ together. This type is recommended when the option type is unknown.
+
+ ::: {#ex-types-anything .example}
+ ::: {.title}
+ **Example: `types.anything` Example**
+ :::
+ Two definitions of this type like
+
+ ```nix
+ {
+ str = lib.mkDefault "foo";
+ pkg.hello = pkgs.hello;
+ fun.fun = x: x + 1;
+ }
+ ```
+
+ ```nix
+ {
+ str = lib.mkIf true "bar";
+ pkg.gcc = pkgs.gcc;
+ fun.fun = lib.mkForce (x: x + 2);
+ }
+ ```
+
+ will get merged to
+
+ ```nix
+ {
+ str = "bar";
+ pkg.gcc = pkgs.gcc;
+ pkg.hello = pkgs.hello;
+ fun.fun = x: x + 2;
+ }
+ ```
+ :::
+
+`types.attrs`
+
+: A free-form attribute set.
+
+ ::: {.warning}
+ This type will be deprecated in the future because it doesn\'t
+ recurse into attribute sets, silently drops earlier attribute
+ definitions, and doesn\'t discharge `lib.mkDefault`, `lib.mkIf`
+ and co. For allowing arbitrary attribute sets, prefer
+ `types.attrsOf types.anything` instead which doesn\'t have these
+ problems.
+ :::
+
+Integer-related types:
+
+`types.int`
+
+: A signed integer.
+
+`types.ints.{s8, s16, s32}`
+
+: Signed integers with a fixed length (8, 16 or 32 bits). They go from
+ −2^n/2 to
+ 2^n/2−1 respectively (e.g. `−128` to
+ `127` for 8 bits).
+
+`types.ints.unsigned`
+
+: An unsigned integer (that is >= 0).
+
+`types.ints.{u8, u16, u32}`
+
+: Unsigned integers with a fixed length (8, 16 or 32 bits). They go
+ from 0 to 2^n−1 respectively (e.g. `0`
+ to `255` for 8 bits).
+
+`types.ints.positive`
+
+: A positive integer (that is > 0).
+
+`types.port`
+
+: A port number. This type is an alias to
+ `types.ints.u16`.
+
+String-related types:
+
+`types.str`
+
+: A string. Multiple definitions cannot be merged.
+
+`types.lines`
+
+: A string. Multiple definitions are concatenated with a new line
+ `"\n"`.
+
+`types.commas`
+
+: A string. Multiple definitions are concatenated with a comma `","`.
+
+`types.envVar`
+
+: A string. Multiple definitions are concatenated with a collon `":"`.
+
+`types.strMatching`
+
+: A string matching a specific regular expression. Multiple
+ definitions cannot be merged. The regular expression is processed
+ using `builtins.match`.
+
+## Value Types {#sec-option-types-value}
+
+Value types are types that take a value parameter.
+
+`types.enum` *`l`*
+
+: One element of the list *`l`*, e.g. `types.enum [ "left" "right" ]`.
+ Multiple definitions cannot be merged.
+
+`types.separatedString` *`sep`*
+
+: A string with a custom separator *`sep`*, e.g.
+ `types.separatedString "|"`.
+
+`types.ints.between` *`lowest highest`*
+
+: An integer between *`lowest`* and *`highest`* (both inclusive). Useful
+ for creating types like `types.port`.
+
+`types.submodule` *`o`*
+
+: A set of sub options *`o`*. *`o`* can be an attribute set, a function
+ returning an attribute set, or a path to a file containing such a
+ value. Submodules are used in composed types to create modular
+ options. This is equivalent to
+ `types.submoduleWith { modules = toList o; shorthandOnlyDefinesConfig = true; }`.
+ Submodules are detailed in [Submodule](#section-option-types-submodule).
+
+`types.submoduleWith` { *`modules`*, *`specialArgs`* ? {}, *`shorthandOnlyDefinesConfig`* ? false }
+
+: Like `types.submodule`, but more flexible and with better defaults.
+ It has parameters
+
+ - *`modules`* A list of modules to use by default for this
+ submodule type. This gets combined with all option definitions
+ to build the final list of modules that will be included.
+
+ ::: {.note}
+ Only options defined with this argument are included in rendered
+ documentation.
+ :::
+
+ - *`specialArgs`* An attribute set of extra arguments to be passed
+ to the module functions. The option `_module.args` should be
+ used instead for most arguments since it allows overriding.
+ *`specialArgs`* should only be used for arguments that can\'t go
+ through the module fixed-point, because of infinite recursion or
+ other problems. An example is overriding the `lib` argument,
+ because `lib` itself is used to define `_module.args`, which
+ makes using `_module.args` to define it impossible.
+
+ - *`shorthandOnlyDefinesConfig`* Whether definitions of this type
+ should default to the `config` section of a module (see
+ [Example: Structure of NixOS Modules](#ex-module-syntax))
+ if it is an attribute set. Enabling this only has a benefit
+ when the submodule defines an option named `config` or `options`.
+ In such a case it would allow the option to be set with
+ `the-submodule.config = "value"` instead of requiring
+ `the-submodule.config.config = "value"`. This is because
+ only when modules *don\'t* set the `config` or `options`
+ keys, all keys are interpreted as option definitions in the
+ `config` section. Enabling this option implicitly puts all
+ attributes in the `config` section.
+
+ With this option enabled, defining a non-`config` section
+ requires using a function:
+ `the-submodule = { ... }: { options = { ... }; }`.
+
+## Composed Types {#sec-option-types-composed}
+
+Composed types are types that take a type as parameter. `listOf
+ int` and `either int str` are examples of composed types.
+
+`types.listOf` *`t`*
+
+: A list of *`t`* type, e.g. `types.listOf
+ int`. Multiple definitions are merged with list concatenation.
+
+`types.attrsOf` *`t`*
+
+: An attribute set of where all the values are of *`t`* type. Multiple
+ definitions result in the joined attribute set.
+
+ ::: {.note}
+ This type is *strict* in its values, which in turn means attributes
+ cannot depend on other attributes. See `
+ types.lazyAttrsOf` for a lazy version.
+ :::
+
+`types.lazyAttrsOf` *`t`*
+
+: An attribute set of where all the values are of *`t`* type. Multiple
+ definitions result in the joined attribute set. This is the lazy
+ version of `types.attrsOf
+ `, allowing attributes to depend on each other.
+
+ ::: {.warning}
+ This version does not fully support conditional definitions! With an
+ option `foo` of this type and a definition
+ `foo.attr = lib.mkIf false 10`, evaluating `foo ? attr` will return
+ `true` even though it should be false. Accessing the value will then
+ throw an error. For types *`t`* that have an `emptyValue` defined,
+ that value will be returned instead of throwing an error. So if the
+ type of `foo.attr` was `lazyAttrsOf (nullOr int)`, `null` would be
+ returned instead for the same `mkIf false` definition.
+ :::
+
+`types.nullOr` *`t`*
+
+: `null` or type *`t`*. Multiple definitions are merged according to
+ type *`t`*.
+
+`types.uniq` *`t`*
+
+: Ensures that type *`t`* cannot be merged. It is used to ensure option
+ definitions are declared only once.
+
+`types.either` *`t1 t2`*
+
+: Type *`t1`* or type *`t2`*, e.g. `with types; either int str`.
+ Multiple definitions cannot be merged.
+
+`types.oneOf` \[ *`t1 t2`* \... \]
+
+: Type *`t1`* or type *`t2`* and so forth, e.g.
+ `with types; oneOf [ int str bool ]`. Multiple definitions cannot be
+ merged.
+
+`types.coercedTo` *`from f to`*
+
+: Type *`to`* or type *`from`* which will be coerced to type *`to`* using
+ function *`f`* which takes an argument of type *`from`* and return a
+ value of type *`to`*. Can be used to preserve backwards compatibility
+ of an option if its type was changed.
+
+## Submodule {#section-option-types-submodule}
+
+`submodule` is a very powerful type that defines a set of sub-options
+that are handled like a separate module.
+
+It takes a parameter *`o`*, that should be a set, or a function returning
+a set with an `options` key defining the sub-options. Submodule option
+definitions are type-checked accordingly to the `options` declarations.
+Of course, you can nest submodule option definitons for even higher
+modularity.
+
+The option set can be defined directly
+([Example: Directly defined submodule](#ex-submodule-direct)) or as reference
+([Example: Submodule defined as a reference](#ex-submodule-reference)).
+
+::: {#ex-submodule-direct .example}
+::: {.title}
+**Example: Directly defined submodule**
+:::
+```nix
+options.mod = mkOption {
+ description = "submodule example";
+ type = with types; submodule {
+ options = {
+ foo = mkOption {
+ type = int;
+ };
+ bar = mkOption {
+ type = str;
+ };
+ };
+ };
+};
+```
+:::
+
+::: {#ex-submodule-reference .example}
+::: {.title}
+**Example: Submodule defined as a reference**
+:::
+```nix
+let
+ modOptions = {
+ options = {
+ foo = mkOption {
+ type = int;
+ };
+ bar = mkOption {
+ type = int;
+ };
+ };
+ };
+in
+options.mod = mkOption {
+ description = "submodule example";
+ type = with types; submodule modOptions;
+};
+```
+:::
+
+The `submodule` type is especially interesting when used with composed
+types like `attrsOf` or `listOf`. When composed with `listOf`
+([Example: Declaration of a list of submodules](#ex-submodule-listof-declaration)), `submodule` allows
+multiple definitions of the submodule option set
+([Example: Definition of a list of submodules](#ex-submodule-listof-definition)).
+
+::: {#ex-submodule-listof-declaration .example}
+::: {.title}
+**Example: Declaration of a list of submodules**
+:::
+```nix
+options.mod = mkOption {
+ description = "submodule example";
+ type = with types; listOf (submodule {
+ options = {
+ foo = mkOption {
+ type = int;
+ };
+ bar = mkOption {
+ type = str;
+ };
+ };
+ });
+};
+```
+:::
+
+::: {#ex-submodule-listof-definition .example}
+::: {.title}
+**Example: Definition of a list of submodules**
+:::
+```nix
+config.mod = [
+ { foo = 1; bar = "one"; }
+ { foo = 2; bar = "two"; }
+];
+```
+:::
+
+When composed with `attrsOf`
+([Example: Declaration of attribute sets of submodules](#ex-submodule-attrsof-declaration)), `submodule` allows
+multiple named definitions of the submodule option set
+([Example: Definition of attribute sets of submodules](#ex-submodule-attrsof-definition)).
+
+::: {#ex-submodule-attrsof-declaration .example}
+::: {.title}
+**Example: Declaration of attribute sets of submodules**
+:::
+```nix
+options.mod = mkOption {
+ description = "submodule example";
+ type = with types; attrsOf (submodule {
+ options = {
+ foo = mkOption {
+ type = int;
+ };
+ bar = mkOption {
+ type = str;
+ };
+ };
+ });
+};
+```
+:::
+
+::: {#ex-submodule-attrsof-definition .example}
+::: {.title}
+**Example: Definition of attribute sets of submodules**
+:::
+```nix
+config.mod.one = { foo = 1; bar = "one"; };
+config.mod.two = { foo = 2; bar = "two"; };
+```
+:::
+
+## Extending types {#sec-option-types-extending}
+
+Types are mainly characterized by their `check` and `merge` functions.
+
+`check`
+
+: The function to type check the value. Takes a value as parameter and
+ return a boolean. It is possible to extend a type check with the
+ `addCheck` function ([Example: Adding a type check](#ex-extending-type-check-1)),
+ or to fully override the check function
+ ([Example: Overriding a type check](#ex-extending-type-check-2)).
+
+ ::: {#ex-extending-type-check-1 .example}
+ ::: {.title}
+ **Example: Adding a type check**
+ :::
+ ```nix
+ byte = mkOption {
+ description = "An integer between 0 and 255.";
+ type = types.addCheck types.int (x: x >= 0 && x <= 255);
+ };
+ ```
+ :::
+
+ ::: {#ex-extending-type-check-2 .example}
+ ::: {.title}
+ **Example: Overriding a type check**
+ :::
+ ```nix
+ nixThings = mkOption {
+ description = "words that start with 'nix'";
+ type = types.str // {
+ check = (x: lib.hasPrefix "nix" x)
+ };
+ };
+ ```
+ :::
+
+`merge`
+
+: Function to merge the options values when multiple values are set.
+ The function takes two parameters, `loc` the option path as a list
+ of strings, and `defs` the list of defined values as a list. It is
+ possible to override a type merge function for custom needs.
+
+## Custom Types {#sec-option-types-custom}
+
+Custom types can be created with the `mkOptionType` function. As type
+creation includes some more complex topics such as submodule handling,
+it is recommended to get familiar with `types.nix` code before creating
+a new type.
+
+The only required parameter is `name`.
+
+`name`
+
+: A string representation of the type function name.
+
+`definition`
+
+: Description of the type used in documentation. Give information of
+ the type and any of its arguments.
+
+`check`
+
+: A function to type check the definition value. Takes the definition
+ value as a parameter and returns a boolean indicating the type check
+ result, `true` for success and `false` for failure.
+
+`merge`
+
+: A function to merge multiple definitions values. Takes two
+ parameters:
+
+ *`loc`*
+
+ : The option path as a list of strings, e.g. `["boot" "loader
+ "grub" "enable"]`.
+
+ *`defs`*
+
+ : The list of sets of defined `value` and `file` where the value
+ was defined, e.g. `[ {
+ file = "/foo.nix"; value = 1; } { file = "/bar.nix"; value = 2 }
+ ]`. The `merge` function should return the merged value
+ or throw an error in case the values are impossible or not meant
+ to be merged.
+
+`getSubOptions`
+
+: For composed types that can take a submodule as type parameter, this
+ function generate sub-options documentation. It takes the current
+ option prefix as a list and return the set of sub-options. Usually
+ defined in a recursive manner by adding a term to the prefix, e.g.
+ `prefix:
+ elemType.getSubOptions (prefix ++
+ ["prefix"])` where *`"prefix"`* is the newly added prefix.
+
+`getSubModules`
+
+: For composed types that can take a submodule as type parameter, this
+ function should return the type parameters submodules. If the type
+ parameter is called `elemType`, the function should just recursively
+ look into submodules by returning `elemType.getSubModules;`.
+
+`substSubModules`
+
+: For composed types that can take a submodule as type parameter, this
+ function can be used to substitute the parameter of a submodule
+ type. It takes a module as parameter and return the type with the
+ submodule options substituted. It is usually defined as a type
+ function call with a recursive call to `substSubModules`, e.g for a
+ type `composedType` that take an `elemtype` type parameter, this
+ function should be defined as `m:
+ composedType (elemType.substSubModules m)`.
+
+`typeMerge`
+
+: A function to merge multiple type declarations. Takes the type to
+ merge `functor` as parameter. A `null` return value means that type
+ cannot be merged.
+
+ *`f`*
+
+ : The type to merge `functor`.
+
+ Note: There is a generic `defaultTypeMerge` that work with most of
+ value and composed types.
+
+`functor`
+
+: An attribute set representing the type. It is used for type
+ operations and has the following keys:
+
+ `type`
+
+ : The type function.
+
+ `wrapped`
+
+ : Holds the type parameter for composed types.
+
+ `payload`
+
+ : Holds the value parameter for value types. The types that have a
+ `payload` are the `enum`, `separatedString` and `submodule`
+ types.
+
+ `binOp`
+
+ : A binary operation that can merge the payloads of two same
+ types. Defined as a function that take two payloads as
+ parameters and return the payloads merged.
diff --git a/nixos/doc/manual/development/option-types.xml b/nixos/doc/manual/development/option-types.xml
deleted file mode 100644
index 3d2191e2f3f3..000000000000
--- a/nixos/doc/manual/development/option-types.xml
+++ /dev/null
@@ -1,914 +0,0 @@
-
- Options Types
-
-
- Option types are a way to put constraints on the values a module option can
- take. Types are also responsible of how values are merged in case of multiple
- value definitions.
-
-
-
- Basic Types
-
-
- Basic types are the simplest available types in the module system. Basic
- types include multiple string types that mainly differ in how definition
- merging is handled.
-
-
-
-
-
- types.bool
-
-
-
- A boolean, its values can be true or
- false.
-
-
-
-
-
- types.path
-
-
-
- A filesystem path, defined as anything that when coerced to a string
- starts with a slash. Even if derivations can be considered as path, the
- more specific types.package should be preferred.
-
-
-
-
-
- types.package
-
-
-
- A derivation or a store path.
-
-
-
-
-
- types.anything
-
-
-
- A type that accepts any value and recursively merges attribute sets together.
- This type is recommended when the option type is unknown.
-
- types.anything Example
-
- Two definitions of this type like
-
-{
- str = lib.mkDefault "foo";
- pkg.hello = pkgs.hello;
- fun.fun = x: x + 1;
-}
-
-
-{
- str = lib.mkIf true "bar";
- pkg.gcc = pkgs.gcc;
- fun.fun = lib.mkForce (x: x + 2);
-}
-
- will get merged to
-
-{
- str = "bar";
- pkg.gcc = pkgs.gcc;
- pkg.hello = pkgs.hello;
- fun.fun = x: x + 2;
-}
-
-
-
-
-
-
-
-
- types.attrs
-
-
-
- A free-form attribute set.
-
- This type will be deprecated in the future because it doesn't recurse
- into attribute sets, silently drops earlier attribute definitions, and
- doesn't discharge lib.mkDefault, lib.mkIf
- and co. For allowing arbitrary attribute sets, prefer
- types.attrsOf types.anything instead which doesn't
- have these problems.
-
-
-
-
-
-
-
- Integer-related types:
-
-
-
-
-
- types.int
-
-
-
- A signed integer.
-
-
-
-
-
- types.ints.{s8, s16, s32}
-
-
-
- Signed integers with a fixed length (8, 16 or 32 bits). They go from
- −2n/2
- to
- 2n/2−1
- respectively (e.g. −128 to
- 127 for 8 bits).
-
-
-
-
-
- types.ints.unsigned
-
-
-
- An unsigned integer (that is >= 0).
-
-
-
-
-
- types.ints.{u8, u16, u32}
-
-
-
- Unsigned integers with a fixed length (8, 16 or 32 bits). They go from
- 0 to
-
- 2n−1
- respectively (e.g. 0 to
- 255 for 8 bits).
-
-
-
-
-
- types.ints.positive
-
-
-
- A positive integer (that is > 0).
-
-
-
-
-
- types.port
-
-
-
- A port number. This type is an alias to
- types.ints.u16.
-
-
-
-
-
-
- String-related types:
-
-
-
-
-
- types.str
-
-
-
- A string. Multiple definitions cannot be merged.
-
-
-
-
-
- types.lines
-
-
-
- A string. Multiple definitions are concatenated with a new line
- "\n".
-
-
-
-
-
- types.commas
-
-
-
- A string. Multiple definitions are concatenated with a comma
- ",".
-
-
-
-
-
- types.envVar
-
-
-
- A string. Multiple definitions are concatenated with a collon
- ":".
-
-
-
-
-
- types.strMatching
-
-
-
- A string matching a specific regular expression. Multiple definitions
- cannot be merged. The regular expression is processed using
- builtins.match.
-
-
-
-
-
-
-
- Value Types
-
-
- Value types are types that take a value parameter.
-
-
-
-
-
- types.enuml
-
-
-
- One element of the list l, e.g.
- types.enum [ "left" "right" ]. Multiple definitions
- cannot be merged.
-
-
-
-
-
- types.separatedStringsep
-
-
-
- A string with a custom separator sep, e.g.
- types.separatedString "|".
-
-
-
-
-
- types.ints.betweenlowesthighest
-
-
-
- An integer between lowest and
- highest (both inclusive). Useful for creating
- types like types.port.
-
-
-
-
-
- types.submoduleo
-
-
-
- A set of sub options o.
- o can be an attribute set, a function
- returning an attribute set, or a path to a file containing such a value. Submodules are used in
- composed types to create modular options. This is equivalent to
- types.submoduleWith { modules = toList o; shorthandOnlyDefinesConfig = true; }.
- Submodules are detailed in
- .
-
-
-
-
-
- types.submoduleWith {
- modules,
- specialArgs ? {},
- shorthandOnlyDefinesConfig ? false }
-
-
-
- Like types.submodule, but more flexible and with better defaults.
- It has parameters
-
-
- modules
- A list of modules to use by default for this submodule type. This gets combined
- with all option definitions to build the final list of modules that will be included.
-
- Only options defined with this argument are included in rendered documentation.
-
-
-
- specialArgs
- An attribute set of extra arguments to be passed to the module functions.
- The option _module.args should be used instead
- for most arguments since it allows overriding. specialArgs should only be
- used for arguments that can't go through the module fixed-point, because of
- infinite recursion or other problems. An example is overriding the
- lib argument, because lib itself is used
- to define _module.args, which makes using
- _module.args to define it impossible.
-
-
- shorthandOnlyDefinesConfig
- Whether definitions of this type should default to the config
- section of a module (see ) if it is an attribute
- set. Enabling this only has a benefit when the submodule defines an option named
- config or options. In such a case it would
- allow the option to be set with the-submodule.config = "value"
- instead of requiring the-submodule.config.config = "value".
- This is because only when modules don't set the
- config or options keys, all keys are interpreted
- as option definitions in the config section. Enabling this option
- implicitly puts all attributes in the config section.
-
-
- With this option enabled, defining a non-config section requires
- using a function: the-submodule = { ... }: { options = { ... }; }.
-
-
-
-
-
-
-
-
-
- Composed Types
-
-
- Composed types are types that take a type as parameter. listOf
- int and either int str are examples of composed
- types.
-
-
-
-
-
- types.listOft
-
-
-
- A list of t type, e.g. types.listOf
- int. Multiple definitions are merged with list concatenation.
-
-
-
-
-
- types.attrsOft
-
-
-
- An attribute set of where all the values are of
- t type. Multiple definitions result in the
- joined attribute set.
-
- This type is strict in its values, which in turn
- means attributes cannot depend on other attributes. See
- types.lazyAttrsOf for a lazy version.
-
-
-
-
-
-
- types.lazyAttrsOft
-
-
-
- An attribute set of where all the values are of
- t type. Multiple definitions result in the
- joined attribute set. This is the lazy version of types.attrsOf
- , allowing attributes to depend on each other.
-
- This version does not fully support conditional definitions! With an
- option foo of this type and a definition
- foo.attr = lib.mkIf false 10, evaluating
- foo ? attr will return true
- even though it should be false. Accessing the value will then throw
- an error. For types t that have an
- emptyValue defined, that value will be returned
- instead of throwing an error. So if the type of foo.attr
- was lazyAttrsOf (nullOr int), null
- would be returned instead for the same mkIf false definition.
-
-
-
-
-
-
- types.nullOrt
-
-
-
- null or type t. Multiple
- definitions are merged according to type t.
-
-
-
-
-
- types.uniqt
-
-
-
- Ensures that type t cannot be merged. It is
- used to ensure option definitions are declared only once.
-
-
-
-
-
- types.eithert1t2
-
-
-
- Type t1 or type t2,
- e.g. with types; either int str. Multiple definitions
- cannot be merged.
-
-
-
-
-
- types.oneOf [ t1t2 ... ]
-
-
-
- Type t1 or type t2 and so forth,
- e.g. with types; oneOf [ int str bool ]. Multiple definitions
- cannot be merged.
-
-
-
-
-
- types.coercedTofromfto
-
-
-
- Type to or type
- from which will be coerced to type
- to using function f
- which takes an argument of type from and
- return a value of type to. Can be used to
- preserve backwards compatibility of an option if its type was changed.
-
-
-
-
-
-
-
- Submodule
-
-
- submodule is a very powerful type that defines a set of
- sub-options that are handled like a separate module.
-
-
-
- It takes a parameter o, that should be a set, or
- a function returning a set with an options key defining
- the sub-options. Submodule option definitions are type-checked accordingly
- to the options declarations. Of course, you can nest
- submodule option definitons for even higher modularity.
-
-
-
- The option set can be defined directly
- () or as reference
- ().
-
-
-
- Directly defined submodule
-
-options.mod = mkOption {
- description = "submodule example";
- type = with types; submodule {
- options = {
- foo = mkOption {
- type = int;
- };
- bar = mkOption {
- type = str;
- };
- };
- };
-};
-
-
-
- Submodule defined as a reference
-
-let
- modOptions = {
- options = {
- foo = mkOption {
- type = int;
- };
- bar = mkOption {
- type = int;
- };
- };
- };
-in
-options.mod = mkOption {
- description = "submodule example";
- type = with types; submodule modOptions;
-};
-
-
-
- The submodule type is especially interesting when used
- with composed types like attrsOf or
- listOf. When composed with listOf
- (),
- submodule allows multiple definitions of the submodule
- option set ().
-
-
-
- Declaration of a list of submodules
-
-options.mod = mkOption {
- description = "submodule example";
- type = with types; listOf (submodule {
- options = {
- foo = mkOption {
- type = int;
- };
- bar = mkOption {
- type = str;
- };
- };
- });
-};
-
-
-
- Definition of a list of submodules
-
-config.mod = [
- { foo = 1; bar = "one"; }
- { foo = 2; bar = "two"; }
-];
-
-
-
- When composed with attrsOf
- (),
- submodule allows multiple named definitions of the
- submodule option set ().
-
-
-
- Declaration of attribute sets of submodules
-
-options.mod = mkOption {
- description = "submodule example";
- type = with types; attrsOf (submodule {
- options = {
- foo = mkOption {
- type = int;
- };
- bar = mkOption {
- type = str;
- };
- };
- });
-};
-
-
-
- Declaration of attribute sets of submodules
-
-config.mod.one = { foo = 1; bar = "one"; };
-config.mod.two = { foo = 2; bar = "two"; };
-
-
-
-
- Extending types
-
-
- Types are mainly characterized by their check and
- merge functions.
-
-
-
-
-
- check
-
-
-
- The function to type check the value. Takes a value as parameter and
- return a boolean. It is possible to extend a type check with the
- addCheck function
- (), or to fully
- override the check function
- ().
-
-
- Adding a type check
-
-byte = mkOption {
- description = "An integer between 0 and 255.";
- type = types.addCheck types.int (x: x >= 0 && x <= 255);
-};
-
-
- Overriding a type check
-
-nixThings = mkOption {
- description = "words that start with 'nix'";
- type = types.str // {
- check = (x: lib.hasPrefix "nix" x)
- };
-};
-
-
-
-
-
- merge
-
-
-
- Function to merge the options values when multiple values are set. The
- function takes two parameters, loc the option path as
- a list of strings, and defs the list of defined values
- as a list. It is possible to override a type merge function for custom
- needs.
-
-
-
-
-
-
-
- Custom Types
-
-
- Custom types can be created with the mkOptionType
- function. As type creation includes some more complex topics such as
- submodule handling, it is recommended to get familiar with
- types.nix
- code before creating a new type.
-
-
-
- The only required parameter is name.
-
-
-
-
-
- name
-
-
-
- A string representation of the type function name.
-
-
-
-
-
- definition
-
-
-
- Description of the type used in documentation. Give information of the
- type and any of its arguments.
-
-
-
-
-
- check
-
-
-
- A function to type check the definition value. Takes the definition value
- as a parameter and returns a boolean indicating the type check result,
- true for success and false for
- failure.
-
-
-
-
-
- merge
-
-
-
- A function to merge multiple definitions values. Takes two parameters:
-
-
-
-
- loc
-
-
-
- The option path as a list of strings, e.g. ["boot" "loader
- "grub" "enable"].
-
-
-
-
-
- defs
-
-
-
- The list of sets of defined value and
- file where the value was defined, e.g. [ {
- file = "/foo.nix"; value = 1; } { file = "/bar.nix"; value = 2 }
- ]. The merge function should return the
- merged value or throw an error in case the values are impossible or
- not meant to be merged.
-
-
-
-
-
-
-
-
- getSubOptions
-
-
-
- For composed types that can take a submodule as type parameter, this
- function generate sub-options documentation. It takes the current option
- prefix as a list and return the set of sub-options. Usually defined in a
- recursive manner by adding a term to the prefix, e.g. prefix:
- elemType.getSubOptions (prefix ++
- ["prefix"]) where
- "prefix" is the newly added prefix.
-
-
-
-
-
- getSubModules
-
-
-
- For composed types that can take a submodule as type parameter, this
- function should return the type parameters submodules. If the type
- parameter is called elemType, the function should just
- recursively look into submodules by returning
- elemType.getSubModules;.
-
-
-
-
-
- substSubModules
-
-
-
- For composed types that can take a submodule as type parameter, this
- function can be used to substitute the parameter of a submodule type. It
- takes a module as parameter and return the type with the submodule
- options substituted. It is usually defined as a type function call with a
- recursive call to substSubModules, e.g for a type
- composedType that take an elemtype
- type parameter, this function should be defined as m:
- composedType (elemType.substSubModules m).
-
-
-
-
-
- typeMerge
-
-
-
- A function to merge multiple type declarations. Takes the type to merge
- functor as parameter. A null return
- value means that type cannot be merged.
-
-
-
-
- f
-
-
-
- The type to merge functor.
-
-
-
-
-
- Note: There is a generic defaultTypeMerge that work
- with most of value and composed types.
-
-
-
-
-
- functor
-
-
-
- An attribute set representing the type. It is used for type operations
- and has the following keys:
-
-
-
-
- type
-
-
-
- The type function.
-
-
-
-
-
- wrapped
-
-
-
- Holds the type parameter for composed types.
-
-
-
-
-
- payload
-
-
-
- Holds the value parameter for value types. The types that have a
- payload are the enum,
- separatedString and submodule
- types.
-
-
-
-
-
- binOp
-
-
-
- A binary operation that can merge the payloads of two same types.
- Defined as a function that take two payloads as parameters and return
- the payloads merged.
-
-
-
-
-
-
-
-
-
diff --git a/nixos/doc/manual/development/writing-modules.xml b/nixos/doc/manual/development/writing-modules.xml
index a1efbeac7232..245c49dbb7eb 100644
--- a/nixos/doc/manual/development/writing-modules.xml
+++ b/nixos/doc/manual/development/writing-modules.xml
@@ -180,7 +180,7 @@ in {
-
+
diff --git a/nixos/doc/manual/from_md/development/option-types.section.xml b/nixos/doc/manual/from_md/development/option-types.section.xml
new file mode 100644
index 000000000000..c83ffa2add53
--- /dev/null
+++ b/nixos/doc/manual/from_md/development/option-types.section.xml
@@ -0,0 +1,987 @@
+
+ Options Types
+
+ Option types are a way to put constraints on the values a module
+ option can take. Types are also responsible of how values are merged
+ in case of multiple value definitions.
+
+
+ Basic Types
+
+ Basic types are the simplest available types in the module system.
+ Basic types include multiple string types that mainly differ in
+ how definition merging is handled.
+
+
+
+
+ types.bool
+
+
+
+ A boolean, its values can be true or
+ false.
+
+
+
+
+
+ types.path
+
+
+
+ A filesystem path, defined as anything that when coerced to
+ a string starts with a slash. Even if derivations can be
+ considered as path, the more specific
+ types.package should be preferred.
+
+
+
+
+
+ types.package
+
+
+
+ A derivation or a store path.
+
+
+
+
+
+ types.anything
+
+
+
+ A type that accepts any value and recursively merges
+ attribute sets together. This type is recommended when the
+ option type is unknown.
+
+
+
+ Example:
+ types.anything Example
+
+
+ Two definitions of this type like
+
+
+{
+ str = lib.mkDefault "foo";
+ pkg.hello = pkgs.hello;
+ fun.fun = x: x + 1;
+}
+
+
+{
+ str = lib.mkIf true "bar";
+ pkg.gcc = pkgs.gcc;
+ fun.fun = lib.mkForce (x: x + 2);
+}
+
+
+ will get merged to
+
+
+{
+ str = "bar";
+ pkg.gcc = pkgs.gcc;
+ pkg.hello = pkgs.hello;
+ fun.fun = x: x + 2;
+}
+
+
+
+
+
+ types.attrs
+
+
+
+ A free-form attribute set.
+
+
+
+ This type will be deprecated in the future because it
+ doesn't recurse into attribute sets, silently drops
+ earlier attribute definitions, and doesn't discharge
+ lib.mkDefault,
+ lib.mkIf and co. For allowing arbitrary
+ attribute sets, prefer
+ types.attrsOf types.anything instead
+ which doesn't have these problems.
+
+
+
+
+
+
+ Integer-related types:
+
+
+
+
+ types.int
+
+
+
+ A signed integer.
+
+
+
+
+
+ types.ints.{s8, s16, s32}
+
+
+
+ Signed integers with a fixed length (8, 16 or 32 bits). They
+ go from −2^n/2 to 2^n/2−1 respectively (e.g.
+ −128 to 127 for 8
+ bits).
+
+
+
+
+
+ types.ints.unsigned
+
+
+
+ An unsigned integer (that is >= 0).
+
+
+
+
+
+ types.ints.{u8, u16, u32}
+
+
+
+ Unsigned integers with a fixed length (8, 16 or 32 bits).
+ They go from 0 to 2^n−1 respectively (e.g.
+ 0 to 255 for 8 bits).
+
+
+
+
+
+ types.ints.positive
+
+
+
+ A positive integer (that is > 0).
+
+
+
+
+
+ types.port
+
+
+
+ A port number. This type is an alias to
+ types.ints.u16.
+
+
+
+
+
+ String-related types:
+
+
+
+
+ types.str
+
+
+
+ A string. Multiple definitions cannot be merged.
+
+
+
+
+
+ types.lines
+
+
+
+ A string. Multiple definitions are concatenated with a new
+ line "\n".
+
+
+
+
+
+ types.commas
+
+
+
+ A string. Multiple definitions are concatenated with a comma
+ ",".
+
+
+
+
+
+ types.envVar
+
+
+
+ A string. Multiple definitions are concatenated with a
+ collon ":".
+
+
+
+
+
+ types.strMatching
+
+
+
+ A string matching a specific regular expression. Multiple
+ definitions cannot be merged. The regular expression is
+ processed using builtins.match.
+
+
+
+
+
+
+ Value Types
+
+ Value types are types that take a value parameter.
+
+
+
+
+ types.enum
+ l
+
+
+
+ One element of the list
+ l, e.g.
+ types.enum [ "left" "right" ].
+ Multiple definitions cannot be merged.
+
+
+
+
+
+ types.separatedString
+ sep
+
+
+
+ A string with a custom separator
+ sep, e.g.
+ types.separatedString "|".
+
+
+
+
+
+ types.ints.between
+ lowest highest
+
+
+
+ An integer between
+ lowest and
+ highest (both
+ inclusive). Useful for creating types like
+ types.port.
+
+
+
+
+
+ types.submodule
+ o
+
+
+
+ A set of sub options
+ o.
+ o can be an
+ attribute set, a function returning an attribute set, or a
+ path to a file containing such a value. Submodules are used
+ in composed types to create modular options. This is
+ equivalent to
+ types.submoduleWith { modules = toList o; shorthandOnlyDefinesConfig = true; }.
+ Submodules are detailed in
+ Submodule.
+
+
+
+
+
+ types.submoduleWith {
+ modules,
+ specialArgs ? {},
+ shorthandOnlyDefinesConfig
+ ? false }
+
+
+
+ Like types.submodule, but more flexible
+ and with better defaults. It has parameters
+
+
+
+
+ modules A list
+ of modules to use by default for this submodule type.
+ This gets combined with all option definitions to build
+ the final list of modules that will be included.
+
+
+
+ Only options defined with this argument are included
+ in rendered documentation.
+
+
+
+
+
+ specialArgs An
+ attribute set of extra arguments to be passed to the
+ module functions. The option
+ _module.args should be used instead
+ for most arguments since it allows overriding.
+ specialArgs
+ should only be used for arguments that can't go through
+ the module fixed-point, because of infinite recursion or
+ other problems. An example is overriding the
+ lib argument, because
+ lib itself is used to define
+ _module.args, which makes using
+ _module.args to define it impossible.
+
+
+
+
+ shorthandOnlyDefinesConfig
+ Whether definitions of this type should default to the
+ config section of a module (see
+ Example: Structure of
+ NixOS Modules) if it is an attribute set.
+ Enabling this only has a benefit when the submodule
+ defines an option named config or
+ options. In such a case it would
+ allow the option to be set with
+ the-submodule.config = "value"
+ instead of requiring
+ the-submodule.config.config = "value".
+ This is because only when modules
+ don't set the
+ config or options
+ keys, all keys are interpreted as option definitions in
+ the config section. Enabling this
+ option implicitly puts all attributes in the
+ config section.
+
+
+ With this option enabled, defining a
+ non-config section requires using a
+ function:
+ the-submodule = { ... }: { options = { ... }; }.
+
+
+
+
+
+
+
+
+ Composed Types
+
+ Composed types are types that take a type as parameter.
+ listOf int and
+ either int str are examples of composed types.
+
+
+
+
+ types.listOf
+ t
+
+
+
+ A list of t type,
+ e.g. types.listOf int. Multiple
+ definitions are merged with list concatenation.
+
+
+
+
+
+ types.attrsOf
+ t
+
+
+
+ An attribute set of where all the values are of
+ t type. Multiple
+ definitions result in the joined attribute set.
+
+
+
+ This type is strict in its values,
+ which in turn means attributes cannot depend on other
+ attributes. See types.lazyAttrsOf for
+ a lazy version.
+
+
+
+
+
+
+ types.lazyAttrsOf
+ t
+
+
+
+ An attribute set of where all the values are of
+ t type. Multiple
+ definitions result in the joined attribute set. This is the
+ lazy version of types.attrsOf , allowing
+ attributes to depend on each other.
+
+
+
+ This version does not fully support conditional
+ definitions! With an option foo of this
+ type and a definition
+ foo.attr = lib.mkIf false 10,
+ evaluating foo ? attr will return
+ true even though it should be false.
+ Accessing the value will then throw an error. For types
+ t that have an
+ emptyValue defined, that value will be
+ returned instead of throwing an error. So if the type of
+ foo.attr was
+ lazyAttrsOf (nullOr int),
+ null would be returned instead for the
+ same mkIf false definition.
+
+
+
+
+
+
+ types.nullOr
+ t
+
+
+
+ null or type
+ t. Multiple
+ definitions are merged according to type
+ t.
+
+
+
+
+
+ types.uniq
+ t
+
+
+
+ Ensures that type t
+ cannot be merged. It is used to ensure option definitions
+ are declared only once.
+
+
+
+
+
+ types.either
+ t1 t2
+
+
+
+ Type t1 or type
+ t2, e.g.
+ with types; either int str. Multiple
+ definitions cannot be merged.
+
+
+
+
+
+ types.oneOf [
+ t1 t2 ... ]
+
+
+
+ Type t1 or type
+ t2 and so forth,
+ e.g. with types; oneOf [ int str bool ].
+ Multiple definitions cannot be merged.
+
+
+
+
+
+ types.coercedTo
+ from f to
+
+
+
+ Type to or type
+ from which will be
+ coerced to type to
+ using function f
+ which takes an argument of type
+ from and return a
+ value of type to.
+ Can be used to preserve backwards compatibility of an option
+ if its type was changed.
+
+
+
+
+
+
+ Submodule
+
+ submodule is a very powerful type that defines
+ a set of sub-options that are handled like a separate module.
+
+
+ It takes a parameter o,
+ that should be a set, or a function returning a set with an
+ options key defining the sub-options. Submodule
+ option definitions are type-checked accordingly to the
+ options declarations. Of course, you can nest
+ submodule option definitons for even higher modularity.
+
+
+ The option set can be defined directly
+ (Example: Directly defined
+ submodule) or as reference
+ (Example: Submodule defined
+ as a reference).
+
+
+
+ Example: Directly defined
+ submodule
+
+
+options.mod = mkOption {
+ description = "submodule example";
+ type = with types; submodule {
+ options = {
+ foo = mkOption {
+ type = int;
+ };
+ bar = mkOption {
+ type = str;
+ };
+ };
+ };
+};
+
+
+
+ Example: Submodule defined as a
+ reference
+
+
+let
+ modOptions = {
+ options = {
+ foo = mkOption {
+ type = int;
+ };
+ bar = mkOption {
+ type = int;
+ };
+ };
+ };
+in
+options.mod = mkOption {
+ description = "submodule example";
+ type = with types; submodule modOptions;
+};
+
+
+ The submodule type is especially interesting
+ when used with composed types like attrsOf or
+ listOf. When composed with
+ listOf
+ (Example:
+ Declaration of a list of submodules),
+ submodule allows multiple definitions of the
+ submodule option set
+ (Example:
+ Definition of a list of submodules).
+
+
+
+ Example: Declaration of a list of
+ submodules
+
+
+options.mod = mkOption {
+ description = "submodule example";
+ type = with types; listOf (submodule {
+ options = {
+ foo = mkOption {
+ type = int;
+ };
+ bar = mkOption {
+ type = str;
+ };
+ };
+ });
+};
+
+
+
+ Example: Definition of a list of
+ submodules
+
+
+config.mod = [
+ { foo = 1; bar = "one"; }
+ { foo = 2; bar = "two"; }
+];
+
+
+ When composed with attrsOf
+ (Example:
+ Declaration of attribute sets of submodules),
+ submodule allows multiple named definitions of
+ the submodule option set
+ (Example:
+ Definition of attribute sets of submodules).
+
+
+
+ Example: Declaration of attribute sets of
+ submodules
+
+
+options.mod = mkOption {
+ description = "submodule example";
+ type = with types; attrsOf (submodule {
+ options = {
+ foo = mkOption {
+ type = int;
+ };
+ bar = mkOption {
+ type = str;
+ };
+ };
+ });
+};
+
+
+
+ Example: Definition of attribute sets of
+ submodules
+
+
+config.mod.one = { foo = 1; bar = "one"; };
+config.mod.two = { foo = 2; bar = "two"; };
+
+
+
+ Extending types
+
+ Types are mainly characterized by their check
+ and merge functions.
+
+
+
+
+ check
+
+
+
+ The function to type check the value. Takes a value as
+ parameter and return a boolean. It is possible to extend a
+ type check with the addCheck function
+ (Example: Adding a
+ type check), or to fully override the check function
+ (Example:
+ Overriding a type check).
+
+
+
+ Example: Adding a type
+ check
+
+
+byte = mkOption {
+ description = "An integer between 0 and 255.";
+ type = types.addCheck types.int (x: x >= 0 && x <= 255);
+};
+
+
+
+ Example: Overriding a type
+ check
+
+
+nixThings = mkOption {
+ description = "words that start with 'nix'";
+ type = types.str // {
+ check = (x: lib.hasPrefix "nix" x)
+ };
+};
+
+
+
+
+
+ merge
+
+
+
+ Function to merge the options values when multiple values
+ are set. The function takes two parameters,
+ loc the option path as a list of strings,
+ and defs the list of defined values as a
+ list. It is possible to override a type merge function for
+ custom needs.
+
+
+
+
+
+
+ Custom Types
+
+ Custom types can be created with the
+ mkOptionType function. As type creation
+ includes some more complex topics such as submodule handling, it
+ is recommended to get familiar with types.nix
+ code before creating a new type.
+
+
+ The only required parameter is name.
+
+
+
+
+ name
+
+
+
+ A string representation of the type function name.
+
+
+
+
+
+ definition
+
+
+
+ Description of the type used in documentation. Give
+ information of the type and any of its arguments.
+
+
+
+
+
+ check
+
+
+
+ A function to type check the definition value. Takes the
+ definition value as a parameter and returns a boolean
+ indicating the type check result, true
+ for success and false for failure.
+
+
+
+
+
+ merge
+
+
+
+ A function to merge multiple definitions values. Takes two
+ parameters:
+
+
+
+
+ loc
+
+
+
+ The option path as a list of strings, e.g.
+ ["boot" "loader "grub" "enable"].
+
+
+
+
+
+ defs
+
+
+
+ The list of sets of defined value
+ and file where the value was
+ defined, e.g.
+ [ { file = "/foo.nix"; value = 1; } { file = "/bar.nix"; value = 2 } ].
+ The merge function should return
+ the merged value or throw an error in case the values
+ are impossible or not meant to be merged.
+
+
+
+
+
+
+
+
+ getSubOptions
+
+
+
+ For composed types that can take a submodule as type
+ parameter, this function generate sub-options documentation.
+ It takes the current option prefix as a list and return the
+ set of sub-options. Usually defined in a recursive manner by
+ adding a term to the prefix, e.g.
+ prefix: elemType.getSubOptions (prefix ++ ["prefix"])
+ where
+ "prefix"
+ is the newly added prefix.
+
+
+
+
+
+ getSubModules
+
+
+
+ For composed types that can take a submodule as type
+ parameter, this function should return the type parameters
+ submodules. If the type parameter is called
+ elemType, the function should just
+ recursively look into submodules by returning
+ elemType.getSubModules;.
+
+
+
+
+
+ substSubModules
+
+
+
+ For composed types that can take a submodule as type
+ parameter, this function can be used to substitute the
+ parameter of a submodule type. It takes a module as
+ parameter and return the type with the submodule options
+ substituted. It is usually defined as a type function call
+ with a recursive call to substSubModules,
+ e.g for a type composedType that take an
+ elemtype type parameter, this function
+ should be defined as
+ m: composedType (elemType.substSubModules m).
+
+
+
+
+
+ typeMerge
+
+
+
+ A function to merge multiple type declarations. Takes the
+ type to merge functor as parameter. A
+ null return value means that type cannot
+ be merged.
+
+
+
+
+ f
+
+
+
+ The type to merge functor.
+
+
+
+
+
+ Note: There is a generic defaultTypeMerge
+ that work with most of value and composed types.
+
+
+
+
+
+ functor
+
+
+
+ An attribute set representing the type. It is used for type
+ operations and has the following keys:
+
+
+
+
+ type
+
+
+
+ The type function.
+
+
+
+
+
+ wrapped
+
+
+
+ Holds the type parameter for composed types.
+
+
+
+
+
+ payload
+
+
+
+ Holds the value parameter for value types. The types
+ that have a payload are the
+ enum,
+ separatedString and
+ submodule types.
+
+
+
+
+
+ binOp
+
+
+
+ A binary operation that can merge the payloads of two
+ same types. Defined as a function that take two
+ payloads as parameters and return the payloads merged.
+
+
+
+
+
+
+
+
+