From ba8b54fa4a91cd94e8c42095d4f82d4a93cd01d1 Mon Sep 17 00:00:00 2001
From: Robert Hensing <robert@roberthensing.nl>
Date: Thu, 27 Sep 2018 18:21:26 +0200
Subject: [PATCH 1/4] Add Nixpkgs functions for adding overlays ad-hoc

This is something that I have found useful in tests. In practice
I recommend that people call Nixpkgs once for performance and
simplicity. The inline documentation mentions this too.
---
 pkgs/top-level/stage.nix | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/pkgs/top-level/stage.nix b/pkgs/top-level/stage.nix
index d0fb885dc747..37724a870a30 100644
--- a/pkgs/top-level/stage.nix
+++ b/pkgs/top-level/stage.nix
@@ -56,7 +56,7 @@
 , # A list of overlays (Additional `self: super: { .. }` customization
   # functions) to be fixed together in the produced package set
   overlays
-}:
+} @args:
 
 let
   stdenvAdapters = self: super:
@@ -159,6 +159,19 @@ let
         };
       };
     };
+
+    # Extend the package set with zero or more overlays. This preserves
+    # preexisting overlays. Prefer to initialize with the right overlays
+    # in one go when calling Nixpkgs, for performance and simplicity.
+    appendOverlays = extraOverlays:
+      import ./stage.nix (args // { overlays = args.overlays ++ extraOverlays; });
+
+    # Extend the package set with a single overlay. This preserves
+    # preexisting overlays. Prefer to initialize with the right overlays
+    # in one go when calling Nixpkgs, for performance and simplicity.
+    # Prefer appendOverlays if used repeatedly.
+    extend = f: self.appendOverlays [f];
+
   };
 
   # The complete chain of package set builders, applied from top to bottom.

From 9b7654f6ff326a7e35b48ce3c54d7f8bb71d9a13 Mon Sep 17 00:00:00 2001
From: Robert Hensing <robert@roberthensing.nl>
Date: Mon, 15 Oct 2018 13:47:36 +0200
Subject: [PATCH 2/4] nixpkgs docs: Point to pkgs.extend, pkgs.appendOverlays
 and improve override section

---
 doc/functions/overrides.xml | 15 +++++++++++++--
 doc/overlays.xml            |  8 +++++++-
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/doc/functions/overrides.xml b/doc/functions/overrides.xml
index 99e2a63631a7..30cc6f3f6b1d 100644
--- a/doc/functions/overrides.xml
+++ b/doc/functions/overrides.xml
@@ -6,8 +6,16 @@
 
  <para>
   Sometimes one wants to override parts of <literal>nixpkgs</literal>, e.g.
-  derivation attributes, the results of derivations or even the whole package
-  set.
+  derivation attributes, the results of derivations.
+ </para>
+
+ <para>
+  These overriding functions let you focus on one part of Nixpkgs and give you
+  back the requested variation. This is orthogonal but related to overlays and
+  the extending functions. Those also let you make modifications but return the
+  whole package set instead of just what you modified. When used together, the
+  override functions make the changes and overlays or extending functions add
+  those changes to the package sets.
  </para>
 
  <section xml:id="sec-pkg-override">
@@ -25,6 +33,9 @@
   <para>
    Example usages:
 <programlisting>pkgs.foo.override { arg1 = val1; arg2 = val2; ... }</programlisting>
+<!-- TODO: move below programlisting to a new section about extending and overlays
+           and reference it
+  -->
 <programlisting>
 import pkgs.path { overlays = [ (self: super: {
   foo = super.foo.override { barSupport = true ; };
diff --git a/doc/overlays.xml b/doc/overlays.xml
index 2decf9febe80..af1ab26b5e97 100644
--- a/doc/overlays.xml
+++ b/doc/overlays.xml
@@ -30,10 +30,16 @@
       itself is given, then that is used.
      </para>
      <para>
-      This can be passed explicitly when importing nipxkgs, for example
+      This can be passed explicitly when importing nixpkgs, for example
       <literal>import &lt;nixpkgs> { overlays = [ overlay1 overlay2 ];
       }</literal>.
      </para>
+     <para>
+      Further overlays can be added by calling the
+      <literal>pkgs.extend</literal> or <literal>pkgs.appendOverlays</literal>,
+      although it is often preferable to avoid these functions, because they
+      recompute the Nixpkgs fixpoint, which is somewhat expensive to do.
+     </para>
     </listitem>
     <listitem>
      <para>

From 3c2ae189c2af388812d82596770df74ac8f839ee Mon Sep 17 00:00:00 2001
From: Robert Hensing <robert@roberthensing.nl>
Date: Thu, 18 Oct 2018 14:01:06 +0200
Subject: [PATCH 3/4] doc: Improve overrides and overlays documentation

---
 doc/functions/overrides.xml |   9 +-
 doc/overlays.xml            | 197 ++++++++++++++++++++----------------
 2 files changed, 114 insertions(+), 92 deletions(-)

diff --git a/doc/functions/overrides.xml b/doc/functions/overrides.xml
index 30cc6f3f6b1d..5532951d1a79 100644
--- a/doc/functions/overrides.xml
+++ b/doc/functions/overrides.xml
@@ -10,12 +10,9 @@
  </para>
 
  <para>
-  These overriding functions let you focus on one part of Nixpkgs and give you
-  back the requested variation. This is orthogonal but related to overlays and
-  the extending functions. Those also let you make modifications but return the
-  whole package set instead of just what you modified. When used together, the
-  override functions make the changes and overlays or extending functions add
-  those changes to the package sets.
+  These functions are used to make changes to packages, returning only single
+  packages. Overlays, on the other hand, can be used to combine the overridden
+  packages across the entire package set of Nixpkgs.
  </para>
 
  <section xml:id="sec-pkg-override">
diff --git a/doc/overlays.xml b/doc/overlays.xml
index af1ab26b5e97..90dd163072d3 100644
--- a/doc/overlays.xml
+++ b/doc/overlays.xml
@@ -17,97 +17,122 @@
   <title>Installing overlays</title>
 
   <para>
-   The list of overlays is determined as follows.
+   The list of overlays can be set either explicitly in a Nix expression, or
+   through <literal>&lt;nixpkgs-overlays></literal> or user configuration
+   files.
   </para>
 
-  <para>
-   If the <varname>overlays</varname> argument is not provided explicitly, we
-   look for overlays in a path. The path is determined as follows:
-   <orderedlist>
-    <listitem>
-     <para>
-      First, if an <varname>overlays</varname> argument to the nixpkgs function
-      itself is given, then that is used.
-     </para>
-     <para>
-      This can be passed explicitly when importing nixpkgs, for example
-      <literal>import &lt;nixpkgs> { overlays = [ overlay1 overlay2 ];
-      }</literal>.
-     </para>
-     <para>
-      Further overlays can be added by calling the
-      <literal>pkgs.extend</literal> or <literal>pkgs.appendOverlays</literal>,
-      although it is often preferable to avoid these functions, because they
-      recompute the Nixpkgs fixpoint, which is somewhat expensive to do.
-     </para>
-    </listitem>
-    <listitem>
-     <para>
-      Otherwise, if the Nix path entry <literal>&lt;nixpkgs-overlays></literal>
-      exists, we look for overlays at that path, as described below.
-     </para>
-     <para>
-      See the section on <literal>NIX_PATH</literal> in the Nix manual for more
-      details on how to set a value for
-      <literal>&lt;nixpkgs-overlays>.</literal>
-     </para>
-    </listitem>
-    <listitem>
-     <para>
-      If one of <filename>~/.config/nixpkgs/overlays.nix</filename> and
-      <filename>~/.config/nixpkgs/overlays/</filename> exists, then we look for
-      overlays at that path, as described below. It is an error if both exist.
-     </para>
-    </listitem>
-   </orderedlist>
-  </para>
+  <section xml:id="sec-overlays-argument">
+   <title>Set overlays in NixOS or Nix expressions</title>
 
-  <para>
-   If we are looking for overlays at a path, then there are two cases:
-   <itemizedlist>
-    <listitem>
-     <para>
-      If the path is a file, then the file is imported as a Nix expression and
-      used as the list of overlays.
-     </para>
-    </listitem>
-    <listitem>
-     <para>
-      If the path is a directory, then we take the content of the directory,
-      order it lexicographically, and attempt to interpret each as an overlay
-      by:
-      <itemizedlist>
-       <listitem>
-        <para>
-         Importing the file, if it is a <literal>.nix</literal> file.
-        </para>
-       </listitem>
-       <listitem>
-        <para>
-         Importing a top-level <filename>default.nix</filename> file, if it is
-         a directory.
-        </para>
-       </listitem>
-      </itemizedlist>
-     </para>
-    </listitem>
-   </itemizedlist>
-  </para>
+   <para>
+    On a NixOS system the value of the <literal>nixpkgs.overlays</literal>
+    option, if present, is passed to the system Nixpkgs directly as an
+    argument. Note that this does not affect the overlays for non-NixOS
+    operations (e.g. <literal>nix-env</literal>), which are
+    <link xlink:href="#sec-overlays-lookup">looked</link> up independently.
+   </para>
 
-  <para>
-   On a NixOS system the value of the <literal>nixpkgs.overlays</literal>
-   option, if present, is passed to the system Nixpkgs directly as an argument.
-   Note that this does not affect the overlays for non-NixOS operations (e.g.
-   <literal>nix-env</literal>), which are looked up independently.
-  </para>
+   <para>
+    The list of overlays can be passed explicitly when importing nixpkgs, for
+    example <literal>import &lt;nixpkgs> { overlays = [ overlay1 overlay2 ];
+    }</literal>.
+   </para>
 
-  <para>
-   The <filename>overlays.nix</filename> option therefore provides a convenient
-   way to use the same overlays for a NixOS system configuration and user
-   configuration: the same file can be used as
-   <filename>overlays.nix</filename> and imported as the value of
-   <literal>nixpkgs.overlays</literal>.
-  </para>
+   <para>
+    Further overlays can be added by calling the <literal>pkgs.extend</literal>
+    or <literal>pkgs.appendOverlays</literal>, although it is often preferable
+    to avoid these functions, because they recompute the Nixpkgs fixpoint,
+    which is somewhat expensive to do.
+   </para>
+  </section>
+
+  <section xml:id="sec-overlays-lookup">
+   <title>Install overlays via configuration lookup</title>
+
+   <para>
+    The list of overlays is determined as follows.
+   </para>
+
+   <para>
+    <orderedlist>
+     <listitem>
+      <para>
+       First, if an
+       <link xlink:href="#sec-overlays-argument"><varname>overlays</varname>
+       argument</link> to the nixpkgs function itself is given, then that is
+       used and no path lookup will be performed.
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       Otherwise, if the Nix path entry
+       <literal>&lt;nixpkgs-overlays></literal> exists, we look for overlays at
+       that path, as described below.
+      </para>
+      <para>
+       See the section on <literal>NIX_PATH</literal> in the Nix manual for
+       more details on how to set a value for
+       <literal>&lt;nixpkgs-overlays>.</literal>
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       If one of <filename>~/.config/nixpkgs/overlays.nix</filename> and
+       <filename>~/.config/nixpkgs/overlays/</filename> exists, then we look
+       for overlays at that path, as described below. It is an error if both
+       exist.
+      </para>
+     </listitem>
+    </orderedlist>
+   </para>
+
+   <para>
+    If we are looking for overlays at a path, then there are two cases:
+    <itemizedlist>
+     <listitem>
+      <para>
+       If the path is a file, then the file is imported as a Nix expression and
+       used as the list of overlays.
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       If the path is a directory, then we take the content of the directory,
+       order it lexicographically, and attempt to interpret each as an overlay
+       by:
+       <itemizedlist>
+        <listitem>
+         <para>
+          Importing the file, if it is a <literal>.nix</literal> file.
+         </para>
+        </listitem>
+        <listitem>
+         <para>
+          Importing a top-level <filename>default.nix</filename> file, if it is
+          a directory.
+         </para>
+        </listitem>
+       </itemizedlist>
+      </para>
+     </listitem>
+    </itemizedlist>
+   </para>
+
+   <para>
+    Because overlays that are set in NixOS configuration do not affect
+    non-NixOS operations such as <literal>nix-env</literal>, the
+    <filename>overlays.nix</filename> option provides a convenient way to use
+    the same overlays for a NixOS system configuration and user configuration:
+    the same file can be used as <filename>overlays.nix</filename> and imported
+    as the value of <literal>nixpkgs.overlays</literal>.
+   </para>
+
+<!-- TODO: Example of sharing overlays between NixOS configuration
+     and configuration lookup. Also reference the example
+     from the sec-overlays-argument paragraph about NixOS.
+ -->
+  </section>
  </section>
 <!--============================================================-->
  <section xml:id="sec-overlays-definition">

From a5c4642ddf03f792c29764c53725f9b04e06decd Mon Sep 17 00:00:00 2001
From: Robert Hensing <robert@roberthensing.nl>
Date: Fri, 19 Oct 2018 12:25:17 +0200
Subject: [PATCH 4/4] doc: Add link from overrides to overlays

---
 doc/functions/overrides.xml | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/doc/functions/overrides.xml b/doc/functions/overrides.xml
index 5532951d1a79..4ba861bd1a42 100644
--- a/doc/functions/overrides.xml
+++ b/doc/functions/overrides.xml
@@ -11,8 +11,9 @@
 
  <para>
   These functions are used to make changes to packages, returning only single
-  packages. Overlays, on the other hand, can be used to combine the overridden
-  packages across the entire package set of Nixpkgs.
+  packages. <link xlink:href="#chap-overlays">Overlays</link>, on the other
+  hand, can be used to combine the overridden packages across the entire
+  package set of Nixpkgs.
  </para>
 
  <section xml:id="sec-pkg-override">