summary refs log tree commit diff
path: root/nixos/doc/manual/development
diff options
context:
space:
mode:
authorBobby Rong <rjl931189261@126.com>2021-07-03 22:16:36 +0800
committerBobby Rong <rjl931189261@126.com>2021-07-03 22:20:55 +0800
commitbfd21cd2c1492b799facdab2e77308c34edbe9e7 (patch)
treea64a8bd3dfeabc62c415aa6c4b591ae28bac3cd7 /nixos/doc/manual/development
parent6877012179ebfbbf47451d2bc8d61212981c7940 (diff)
downloadnixpkgs-bfd21cd2c1492b799facdab2e77308c34edbe9e7.tar
nixpkgs-bfd21cd2c1492b799facdab2e77308c34edbe9e7.tar.gz
nixpkgs-bfd21cd2c1492b799facdab2e77308c34edbe9e7.tar.bz2
nixpkgs-bfd21cd2c1492b799facdab2e77308c34edbe9e7.tar.lz
nixpkgs-bfd21cd2c1492b799facdab2e77308c34edbe9e7.tar.xz
nixpkgs-bfd21cd2c1492b799facdab2e77308c34edbe9e7.tar.zst
nixpkgs-bfd21cd2c1492b799facdab2e77308c34edbe9e7.zip
nixos: nixos/doc/manual/development/option-types.xml to CommonMark
Diffstat (limited to 'nixos/doc/manual/development')
-rw-r--r--nixos/doc/manual/development/option-types.section.md558
-rw-r--r--nixos/doc/manual/development/option-types.xml914
-rw-r--r--nixos/doc/manual/development/writing-modules.xml2
3 files changed, 559 insertions, 915 deletions
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 00000000000..ed557206659
--- /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 3d2191e2f3f..00000000000
--- a/nixos/doc/manual/development/option-types.xml
+++ /dev/null
@@ -1,914 +0,0 @@
-<section xmlns="http://docbook.org/ns/docbook"
-        xmlns:xlink="http://www.w3.org/1999/xlink"
-        xmlns:xi="http://www.w3.org/2001/XInclude"
-        version="5.0"
-        xml:id="sec-option-types">
- <title>Options Types</title>
-
- <para>
-  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.
- </para>
-
- <section xml:id="sec-option-types-basic">
-  <title>Basic Types</title>
-
-  <para>
-   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.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>types.bool</varname>
-    </term>
-    <listitem>
-     <para>
-      A boolean, its values can be <literal>true</literal> or
-      <literal>false</literal>.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.path</varname>
-    </term>
-    <listitem>
-     <para>
-      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 <literal>types.package</literal> should be preferred.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.package</varname>
-    </term>
-    <listitem>
-     <para>
-      A derivation or a store path.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.anything</varname>
-    </term>
-    <listitem>
-     <para>
-      A type that accepts any value and recursively merges attribute sets together.
-      This type is recommended when the option type is unknown.
-      <example xml:id="ex-types-anything">
-       <title><literal>types.anything</literal> Example</title>
-       <para>
-        Two definitions of this type like
-<programlisting>
-{
-  str = lib.mkDefault "foo";
-  pkg.hello = pkgs.hello;
-  fun.fun = x: x + 1;
-}
-</programlisting>
-<programlisting>
-{
-  str = lib.mkIf true "bar";
-  pkg.gcc = pkgs.gcc;
-  fun.fun = lib.mkForce (x: x + 2);
-}
-</programlisting>
-        will get merged to
-<programlisting>
-{
-  str = "bar";
-  pkg.gcc = pkgs.gcc;
-  pkg.hello = pkgs.hello;
-  fun.fun = x: x + 2;
-}
-</programlisting>
-       </para>
-      </example>
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.attrs</varname>
-    </term>
-    <listitem>
-     <para>
-      A free-form attribute set.
-      <warning><para>
-       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 <literal>lib.mkDefault</literal>, <literal>lib.mkIf
-       </literal> and co. For allowing arbitrary attribute sets, prefer
-       <literal>types.attrsOf types.anything</literal> instead which doesn't
-       have these problems.
-      </para></warning>
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <para>
-   Integer-related types:
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>types.int</varname>
-    </term>
-    <listitem>
-     <para>
-      A signed integer.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.ints.{s8, s16, s32}</varname>
-    </term>
-    <listitem>
-     <para>
-      Signed integers with a fixed length (8, 16 or 32 bits). They go from
-      <inlineequation><mathphrase>−2<superscript>n</superscript>/2</mathphrase>
-      </inlineequation> to <inlineequation>
-      <mathphrase>2<superscript>n</superscript>/2−1</mathphrase>
-      </inlineequation> respectively (e.g. <literal>−128</literal> to
-      <literal>127</literal> for 8 bits).
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.ints.unsigned</varname>
-    </term>
-    <listitem>
-     <para>
-      An unsigned integer (that is >= 0).
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry xml:id='types.ints.ux'>
-    <term>
-     <varname>types.ints.{u8, u16, u32}</varname>
-    </term>
-    <listitem>
-     <para>
-      Unsigned integers with a fixed length (8, 16 or 32 bits). They go from
-      <inlineequation><mathphrase>0</mathphrase></inlineequation> to
-      <inlineequation>
-      <mathphrase>2<superscript>n</superscript>−1</mathphrase>
-      </inlineequation> respectively (e.g. <literal>0</literal> to
-      <literal>255</literal> for 8 bits).
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.ints.positive</varname>
-    </term>
-    <listitem>
-     <para>
-      A positive integer (that is > 0).
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.port</varname>
-    </term>
-    <listitem>
-     <para>
-      A port number. This type is an alias to
-      <link linkend='types.ints.ux'><varname>types.ints.u16</varname></link>.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <para>
-   String-related types:
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>types.str</varname>
-    </term>
-    <listitem>
-     <para>
-      A string. Multiple definitions cannot be merged.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.lines</varname>
-    </term>
-    <listitem>
-     <para>
-      A string. Multiple definitions are concatenated with a new line
-      <literal>"\n"</literal>.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.commas</varname>
-    </term>
-    <listitem>
-     <para>
-      A string. Multiple definitions are concatenated with a comma
-      <literal>","</literal>.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.envVar</varname>
-    </term>
-    <listitem>
-     <para>
-      A string. Multiple definitions are concatenated with a collon
-      <literal>":"</literal>.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.strMatching</varname>
-    </term>
-    <listitem>
-     <para>
-      A string matching a specific regular expression. Multiple definitions
-      cannot be merged. The regular expression is processed using
-      <literal>builtins.match</literal>.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
- </section>
-
- <section xml:id="sec-option-types-value">
-  <title>Value Types</title>
-
-  <para>
-   Value types are types that take a value parameter.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>types.enum</varname> <replaceable>l</replaceable>
-    </term>
-    <listitem>
-     <para>
-      One element of the list <replaceable>l</replaceable>, e.g.
-      <literal>types.enum [ "left" "right" ]</literal>. Multiple definitions
-      cannot be merged.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.separatedString</varname> <replaceable>sep</replaceable>
-    </term>
-    <listitem>
-     <para>
-      A string with a custom separator <replaceable>sep</replaceable>, e.g.
-      <literal>types.separatedString "|"</literal>.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.ints.between</varname> <replaceable>lowest</replaceable> <replaceable>highest</replaceable>
-    </term>
-    <listitem>
-     <para>
-      An integer between <replaceable>lowest</replaceable> and
-      <replaceable>highest</replaceable> (both inclusive). Useful for creating
-      types like <literal>types.port</literal>.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.submodule</varname> <replaceable>o</replaceable>
-    </term>
-    <listitem>
-     <para>
-      A set of sub options <replaceable>o</replaceable>.
-      <replaceable>o</replaceable> 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
-      <literal>types.submoduleWith { modules = toList o; shorthandOnlyDefinesConfig = true; }</literal>.
-      Submodules are detailed in
-      <xref
-          linkend='section-option-types-submodule' />.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-     <term>
-       <varname>types.submoduleWith</varname> {
-        <replaceable>modules</replaceable>,
-        <replaceable>specialArgs</replaceable> ? {},
-        <replaceable>shorthandOnlyDefinesConfig</replaceable> ? false }
-     </term>
-     <listitem>
-       <para>
-         Like <varname>types.submodule</varname>, but more flexible and with better defaults.
-         It has parameters
-         <itemizedlist>
-           <listitem><para>
-             <replaceable>modules</replaceable>
-             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><para>
-               Only options defined with this argument are included in rendered documentation.
-             </para></note>
-           </para></listitem>
-           <listitem><para>
-             <replaceable>specialArgs</replaceable>
-             An attribute set of extra arguments to be passed to the module functions.
-             The option <literal>_module.args</literal> should be used instead
-             for most arguments since it allows overriding. <replaceable>specialArgs</replaceable> should only be
-             used for arguments that can&apos;t go through the module fixed-point, because of
-             infinite recursion or other problems. An example is overriding the
-             <varname>lib</varname> argument, because <varname>lib</varname> itself is used
-             to define <literal>_module.args</literal>, which makes using
-             <literal>_module.args</literal> to define it impossible.
-           </para></listitem>
-           <listitem><para>
-             <replaceable>shorthandOnlyDefinesConfig</replaceable>
-             Whether definitions of this type should default to the <literal>config</literal>
-             section of a module (see <xref linkend='ex-module-syntax'/>) if it is an attribute
-             set. Enabling this only has a benefit when the submodule defines an option named
-             <literal>config</literal> or <literal>options</literal>. In such a case it would
-             allow the option to be set with <literal>the-submodule.config = "value"</literal>
-             instead of requiring <literal>the-submodule.config.config = "value"</literal>.
-             This is because only when modules <emphasis>don&apos;t</emphasis> set the
-             <literal>config</literal> or <literal>options</literal> keys, all keys are interpreted
-             as option definitions in the <literal>config</literal> section. Enabling this option
-             implicitly puts all attributes in the <literal>config</literal> section.
-           </para>
-           <para>
-             With this option enabled, defining a non-<literal>config</literal> section requires
-             using a function: <literal>the-submodule = { ... }: { options = { ... }; }</literal>.
-           </para></listitem>
-         </itemizedlist>
-       </para>
-     </listitem>
-   </varlistentry>
-  </variablelist>
- </section>
-
- <section xml:id="sec-option-types-composed">
-  <title>Composed Types</title>
-
-  <para>
-   Composed types are types that take a type as parameter. <literal>listOf
-   int</literal> and <literal>either int str</literal> are examples of composed
-   types.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>types.listOf</varname> <replaceable>t</replaceable>
-    </term>
-    <listitem>
-     <para>
-      A list of <replaceable>t</replaceable> type, e.g. <literal>types.listOf
-      int</literal>. Multiple definitions are merged with list concatenation.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.attrsOf</varname> <replaceable>t</replaceable>
-    </term>
-    <listitem>
-     <para>
-      An attribute set of where all the values are of
-      <replaceable>t</replaceable> type. Multiple definitions result in the
-      joined attribute set.
-      <note><para>
-       This type is <emphasis>strict</emphasis> in its values, which in turn
-       means attributes cannot depend on other attributes. See <varname>
-       types.lazyAttrsOf</varname> for a lazy version.
-      </para></note>
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.lazyAttrsOf</varname> <replaceable>t</replaceable>
-    </term>
-    <listitem>
-     <para>
-      An attribute set of where all the values are of
-      <replaceable>t</replaceable> type. Multiple definitions result in the
-      joined attribute set. This is the lazy version of <varname>types.attrsOf
-      </varname>, allowing attributes to depend on each other.
-      <warning><para>
-       This version does not fully support conditional definitions! With an
-       option <varname>foo</varname> of this type and a definition
-       <literal>foo.attr = lib.mkIf false 10</literal>, evaluating
-       <literal>foo ? attr</literal> will return <literal>true</literal>
-       even though it should be false. Accessing the value will then throw
-       an error. For types <replaceable>t</replaceable> that have an
-       <literal>emptyValue</literal> defined, that value will be returned
-       instead of throwing an error. So if the type of <literal>foo.attr</literal>
-       was <literal>lazyAttrsOf (nullOr int)</literal>, <literal>null</literal>
-       would be returned instead for the same <literal>mkIf false</literal> definition.
-      </para></warning>
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.nullOr</varname> <replaceable>t</replaceable>
-    </term>
-    <listitem>
-     <para>
-      <literal>null</literal> or type <replaceable>t</replaceable>. Multiple
-      definitions are merged according to type <replaceable>t</replaceable>.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.uniq</varname> <replaceable>t</replaceable>
-    </term>
-    <listitem>
-     <para>
-      Ensures that type <replaceable>t</replaceable> cannot be merged. It is
-      used to ensure option definitions are declared only once.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.either</varname> <replaceable>t1</replaceable> <replaceable>t2</replaceable>
-    </term>
-    <listitem>
-     <para>
-      Type <replaceable>t1</replaceable> or type <replaceable>t2</replaceable>,
-      e.g. <literal>with types; either int str</literal>. Multiple definitions
-      cannot be merged.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.oneOf</varname> [ <replaceable>t1</replaceable> <replaceable>t2</replaceable> ... ]
-    </term>
-    <listitem>
-     <para>
-      Type <replaceable>t1</replaceable> or type <replaceable>t2</replaceable> and so forth,
-      e.g. <literal>with types; oneOf [ int str bool ]</literal>. Multiple definitions
-      cannot be merged.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>types.coercedTo</varname> <replaceable>from</replaceable> <replaceable>f</replaceable> <replaceable>to</replaceable>
-    </term>
-    <listitem>
-     <para>
-      Type <replaceable>to</replaceable> or type
-      <replaceable>from</replaceable> which will be coerced to type
-      <replaceable>to</replaceable> using function <replaceable>f</replaceable>
-      which takes an argument of type <replaceable>from</replaceable> and
-      return a value of type <replaceable>to</replaceable>. Can be used to
-      preserve backwards compatibility of an option if its type was changed.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
- </section>
-
- <section xml:id='section-option-types-submodule'>
-  <title>Submodule</title>
-
-  <para>
-   <literal>submodule</literal> is a very powerful type that defines a set of
-   sub-options that are handled like a separate module.
-  </para>
-
-  <para>
-   It takes a parameter <replaceable>o</replaceable>, that should be a set, or
-   a function returning a set with an <literal>options</literal> key defining
-   the sub-options. Submodule option definitions are type-checked accordingly
-   to the <literal>options</literal> declarations. Of course, you can nest
-   submodule option definitons for even higher modularity.
-  </para>
-
-  <para>
-   The option set can be defined directly
-   (<xref linkend='ex-submodule-direct' />) or as reference
-   (<xref linkend='ex-submodule-reference' />).
-  </para>
-
-  <example xml:id='ex-submodule-direct'>
-   <title>Directly defined submodule</title>
-<screen>
-options.mod = mkOption {
-  description = "submodule example";
-  type = with types; submodule {
-    options = {
-      foo = mkOption {
-        type = int;
-      };
-      bar = mkOption {
-        type = str;
-      };
-    };
-  };
-};</screen>
-  </example>
-
-  <example xml:id='ex-submodule-reference'>
-   <title>Submodule defined as a reference</title>
-<screen>
-let
-  modOptions = {
-    options = {
-      foo = mkOption {
-        type = int;
-      };
-      bar = mkOption {
-        type = int;
-      };
-    };
-  };
-in
-options.mod = mkOption {
-  description = "submodule example";
-  type = with types; submodule modOptions;
-};</screen>
-  </example>
-
-  <para>
-   The <literal>submodule</literal> type is especially interesting when used
-   with composed types like <literal>attrsOf</literal> or
-   <literal>listOf</literal>. When composed with <literal>listOf</literal>
-   (<xref linkend='ex-submodule-listof-declaration' />),
-   <literal>submodule</literal> allows multiple definitions of the submodule
-   option set (<xref linkend='ex-submodule-listof-definition' />).
-  </para>
-
-  <example xml:id='ex-submodule-listof-declaration'>
-   <title>Declaration of a list of submodules</title>
-<screen>
-options.mod = mkOption {
-  description = "submodule example";
-  type = with types; listOf (submodule {
-    options = {
-      foo = mkOption {
-        type = int;
-      };
-      bar = mkOption {
-        type = str;
-      };
-    };
-  });
-};</screen>
-  </example>
-
-  <example xml:id='ex-submodule-listof-definition'>
-   <title>Definition of a list of submodules</title>
-<screen>
-config.mod = [
-  { foo = 1; bar = "one"; }
-  { foo = 2; bar = "two"; }
-];</screen>
-  </example>
-
-  <para>
-   When composed with <literal>attrsOf</literal>
-   (<xref linkend='ex-submodule-attrsof-declaration' />),
-   <literal>submodule</literal> allows multiple named definitions of the
-   submodule option set (<xref linkend='ex-submodule-attrsof-definition' />).
-  </para>
-
-  <example xml:id='ex-submodule-attrsof-declaration'>
-   <title>Declaration of attribute sets of submodules</title>
-<screen>
-options.mod = mkOption {
-  description = "submodule example";
-  type = with types; attrsOf (submodule {
-    options = {
-      foo = mkOption {
-        type = int;
-      };
-      bar = mkOption {
-        type = str;
-      };
-    };
-  });
-};</screen>
-  </example>
-
-  <example xml:id='ex-submodule-attrsof-definition'>
-   <title>Declaration of attribute sets of submodules</title>
-<screen>
-config.mod.one = { foo = 1; bar = "one"; };
-config.mod.two = { foo = 2; bar = "two"; };</screen>
-  </example>
- </section>
-
- <section xml:id="sec-option-types-extending">
-  <title>Extending types</title>
-
-  <para>
-   Types are mainly characterized by their <literal>check</literal> and
-   <literal>merge</literal> functions.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>check</varname>
-    </term>
-    <listitem>
-     <para>
-      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
-      <literal>addCheck</literal> function
-      (<xref
-          linkend='ex-extending-type-check-1' />), or to fully
-      override the check function
-      (<xref linkend='ex-extending-type-check-2' />).
-     </para>
-     <example xml:id='ex-extending-type-check-1'>
-      <title>Adding a type check</title>
-<screen>
-byte = mkOption {
-  description = "An integer between 0 and 255.";
-  type = types.addCheck types.int (x: x &gt;= 0 &amp;&amp; x &lt;= 255);
-};</screen>
-     </example>
-     <example xml:id='ex-extending-type-check-2'>
-      <title>Overriding a type check</title>
-<screen>
-nixThings = mkOption {
-  description = "words that start with 'nix'";
-  type = types.str // {
-    check = (x: lib.hasPrefix "nix" x)
-  };
-};</screen>
-     </example>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>merge</varname>
-    </term>
-    <listitem>
-     <para>
-      Function to merge the options values when multiple values are set. The
-      function takes two parameters, <literal>loc</literal> the option path as
-      a list of strings, and <literal>defs</literal> the list of defined values
-      as a list. It is possible to override a type merge function for custom
-      needs.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
- </section>
-
- <section xml:id="sec-option-types-custom">
-  <title>Custom Types</title>
-
-  <para>
-   Custom types can be created with the <literal>mkOptionType</literal>
-   function. As type creation includes some more complex topics such as
-   submodule handling, it is recommended to get familiar with
-   <filename
-  xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/types.nix">types.nix</filename>
-   code before creating a new type.
-  </para>
-
-  <para>
-   The only required parameter is <literal>name</literal>.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>name</varname>
-    </term>
-    <listitem>
-     <para>
-      A string representation of the type function name.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>definition</varname>
-    </term>
-    <listitem>
-     <para>
-      Description of the type used in documentation. Give information of the
-      type and any of its arguments.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>check</varname>
-    </term>
-    <listitem>
-     <para>
-      A function to type check the definition value. Takes the definition value
-      as a parameter and returns a boolean indicating the type check result,
-      <literal>true</literal> for success and <literal>false</literal> for
-      failure.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>merge</varname>
-    </term>
-    <listitem>
-     <para>
-      A function to merge multiple definitions values. Takes two parameters:
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <replaceable>loc</replaceable>
-       </term>
-       <listitem>
-        <para>
-         The option path as a list of strings, e.g. <literal>["boot" "loader
-         "grub" "enable"]</literal>.
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <replaceable>defs</replaceable>
-       </term>
-       <listitem>
-        <para>
-         The list of sets of defined <literal>value</literal> and
-         <literal>file</literal> where the value was defined, e.g. <literal>[ {
-         file = "/foo.nix"; value = 1; } { file = "/bar.nix"; value = 2 }
-         ]</literal>. The <literal>merge</literal> function should return the
-         merged value or throw an error in case the values are impossible or
-         not meant to be merged.
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>getSubOptions</varname>
-    </term>
-    <listitem>
-     <para>
-      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. <literal>prefix:
-      elemType.getSubOptions (prefix ++
-      [<replaceable>"prefix"</replaceable>])</literal> where
-      <replaceable>"prefix"</replaceable> is the newly added prefix.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>getSubModules</varname>
-    </term>
-    <listitem>
-     <para>
-      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 <literal>elemType</literal>, the function should just
-      recursively look into submodules by returning
-      <literal>elemType.getSubModules;</literal>.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>substSubModules</varname>
-    </term>
-    <listitem>
-     <para>
-      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 <literal>substSubModules</literal>, e.g for a type
-      <literal>composedType</literal> that take an <literal>elemtype</literal>
-      type parameter, this function should be defined as <literal>m:
-      composedType (elemType.substSubModules m)</literal>.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>typeMerge</varname>
-    </term>
-    <listitem>
-     <para>
-      A function to merge multiple type declarations. Takes the type to merge
-      <literal>functor</literal> as parameter. A <literal>null</literal> return
-      value means that type cannot be merged.
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <replaceable>f</replaceable>
-       </term>
-       <listitem>
-        <para>
-         The type to merge <literal>functor</literal>.
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-     <para>
-      Note: There is a generic <literal>defaultTypeMerge</literal> that work
-      with most of value and composed types.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>functor</varname>
-    </term>
-    <listitem>
-     <para>
-      An attribute set representing the type. It is used for type operations
-      and has the following keys:
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <varname>type</varname>
-       </term>
-       <listitem>
-        <para>
-         The type function.
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <varname>wrapped</varname>
-       </term>
-       <listitem>
-        <para>
-         Holds the type parameter for composed types.
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <varname>payload</varname>
-       </term>
-       <listitem>
-        <para>
-         Holds the value parameter for value types. The types that have a
-         <literal>payload</literal> are the <literal>enum</literal>,
-         <literal>separatedString</literal> and <literal>submodule</literal>
-         types.
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <varname>binOp</varname>
-       </term>
-       <listitem>
-        <para>
-         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.
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-    </listitem>
-   </varlistentry>
-  </variablelist>
- </section>
-</section>
diff --git a/nixos/doc/manual/development/writing-modules.xml b/nixos/doc/manual/development/writing-modules.xml
index a1efbeac723..245c49dbb7e 100644
--- a/nixos/doc/manual/development/writing-modules.xml
+++ b/nixos/doc/manual/development/writing-modules.xml
@@ -180,7 +180,7 @@ in {
 </programlisting>
  </example>
  <xi:include href="../from_md/development/option-declarations.section.xml" />
- <xi:include href="option-types.xml" />
+ <xi:include href="../from_md/development/option-types.section.xml" />
  <xi:include href="option-def.xml" />
  <xi:include href="../from_md/development/assertions.section.xml" />
  <xi:include href="meta-attributes.xml" />