···6666 and returning a set with TOML-specific attributes `type` and
6767 `generate` as specified [below](#pkgs-formats-result).
68686969+`pkgs.formats.elixirConf { elixir ? pkgs.elixir }`
7070+7171+: A function taking an attribute set with values
7272+7373+ `elixir`
7474+7575+ : The Elixir package which will be used to format the generated output
7676+7777+ It returns a set with Elixir-Config-specific attributes `type`, `lib`, and
7878+ `generate` as specified [below](#pkgs-formats-result).
7979+8080+ The `lib` attribute contains functions to be used in settings, for
8181+ generating special Elixir values:
8282+8383+ `mkRaw elixirCode`
8484+8585+ : Outputs the given string as raw Elixir code
8686+8787+ `mkGetEnv { envVariable, fallback ? null }`
8888+8989+ : Makes the configuration fetch an environment variable at runtime
9090+9191+ `mkAtom atom`
9292+9393+ : Outputs the given string as an Elixir atom, instead of the default
9494+ Elixir binary string. Note: lowercase atoms still needs to be prefixed
9595+ with `:`
9696+9797+ `mkTuple array`
9898+9999+ : Outputs the given array as an Elixir tuple, instead of the default
100100+ Elixir list
101101+102102+ `mkMap attrset`
103103+104104+ : Outputs the given attribute set as an Elixir map, instead of the
105105+ default Elixir keyword list
106106+107107+69108::: {#pkgs-formats-result}
70109These functions all return an attribute set with these values:
71110:::
···73112`type`
7411375114: A module system type representing a value of the format
115115+116116+`lib`
117117+118118+: Utility functions for convenience, or special interactions with the format.
119119+ This attribute is optional. It may contain inside a `types` attribute
120120+ containing types specific to this format.
7612177122`generate` *`filename jsonValue`*
78123
···137137 </para>
138138 </listitem>
139139 </varlistentry>
140140+ <varlistentry>
141141+ <term>
142142+ <literal>pkgs.formats.elixirConf { elixir ? pkgs.elixir }</literal>
143143+ </term>
144144+ <listitem>
145145+ <para>
146146+ A function taking an attribute set with values
147147+ </para>
148148+ <variablelist>
149149+ <varlistentry>
150150+ <term>
151151+ <literal>elixir</literal>
152152+ </term>
153153+ <listitem>
154154+ <para>
155155+ The Elixir package which will be used to format the
156156+ generated output
157157+ </para>
158158+ </listitem>
159159+ </varlistentry>
160160+ </variablelist>
161161+ <para>
162162+ It returns a set with Elixir-Config-specific attributes
163163+ <literal>type</literal>, <literal>lib</literal>, and
164164+ <literal>generate</literal> as specified
165165+ <link linkend="pkgs-formats-result">below</link>.
166166+ </para>
167167+ <para>
168168+ The <literal>lib</literal> attribute contains functions to
169169+ be used in settings, for generating special Elixir values:
170170+ </para>
171171+ <variablelist>
172172+ <varlistentry>
173173+ <term>
174174+ <literal>mkRaw elixirCode</literal>
175175+ </term>
176176+ <listitem>
177177+ <para>
178178+ Outputs the given string as raw Elixir code
179179+ </para>
180180+ </listitem>
181181+ </varlistentry>
182182+ <varlistentry>
183183+ <term>
184184+ <literal>mkGetEnv { envVariable, fallback ? null }</literal>
185185+ </term>
186186+ <listitem>
187187+ <para>
188188+ Makes the configuration fetch an environment variable
189189+ at runtime
190190+ </para>
191191+ </listitem>
192192+ </varlistentry>
193193+ <varlistentry>
194194+ <term>
195195+ <literal>mkAtom atom</literal>
196196+ </term>
197197+ <listitem>
198198+ <para>
199199+ Outputs the given string as an Elixir atom, instead of
200200+ the default Elixir binary string. Note: lowercase
201201+ atoms still needs to be prefixed with
202202+ <literal>:</literal>
203203+ </para>
204204+ </listitem>
205205+ </varlistentry>
206206+ <varlistentry>
207207+ <term>
208208+ <literal>mkTuple array</literal>
209209+ </term>
210210+ <listitem>
211211+ <para>
212212+ Outputs the given array as an Elixir tuple, instead of
213213+ the default Elixir list
214214+ </para>
215215+ </listitem>
216216+ </varlistentry>
217217+ <varlistentry>
218218+ <term>
219219+ <literal>mkMap attrset</literal>
220220+ </term>
221221+ <listitem>
222222+ <para>
223223+ Outputs the given attribute set as an Elixir map,
224224+ instead of the default Elixir keyword list
225225+ </para>
226226+ </listitem>
227227+ </varlistentry>
228228+ </variablelist>
229229+ </listitem>
230230+ </varlistentry>
140231 </variablelist>
141232 <para xml:id="pkgs-formats-result">
142233 These functions all return an attribute set with these values:
···149240 <listitem>
150241 <para>
151242 A module system type representing a value of the format
243243+ </para>
244244+ </listitem>
245245+ </varlistentry>
246246+ <varlistentry>
247247+ <term>
248248+ <literal>lib</literal>
249249+ </term>
250250+ <listitem>
251251+ <para>
252252+ Utility functions for convenience, or special interactions
253253+ with the format. This attribute is optional. It may contain
254254+ inside a <literal>types</literal> attribute containing types
255255+ specific to this format.
152256 </para>
153257 </listitem>
154258 </varlistentry>
···44 pname = "nerd-font-patcher";
55 version = "2.1.0";
6677- # The size of the nerd fonts repository is bigger than 2GB, because it
88- # contains a lot of fonts and the patcher.
99- # until https://github.com/ryanoasis/nerd-fonts/issues/484 is not fixed,
1010- # we download the patcher from an alternative repository
77+ # This uses a sparse checkout because the repo is >2GB without it
118 src = fetchFromGitHub {
1212- owner = "betaboon";
1313- repo = "nerd-fonts-patcher";
1414- rev = "180684d7a190f75fd2fea7ca1b26c6540db8d3c0";
1515- sha256 = "sha256-FAbdLf0XiUXGltAgmq33Wqv6PFo/5qCv62UxXnj3SgI=";
99+ owner = "ryanoasis";
1010+ repo = "nerd-fonts";
1111+ rev = "v${version}";
1212+ sparseCheckout = ''
1313+ font-patcher
1414+ /src/glyphs
1515+ '';
1616+ sha256 = "sha256-ePBlEVjzAJ7g6iAGIqPfgZ8bwtNILmyEVm0zD+xNN6k=";
1617 };
17181819 propagatedBuildInputs = with python3Packages; [ fontforge ];
···1414 # The description needs to be overwritten for recursive types
1515 type = ...;
16161717+ # Utility functions for convenience, or special interactions with the
1818+ # format (optional)
1919+ lib = {
2020+ exampleFunction = ...
2121+ # Types specific to the format (optional)
2222+ types = { ... };
2323+ ...
2424+ };
2525+1726 # generate :: Name -> Value -> Path
1827 # A function for generating a file with a value of such a type
1928 generate = ...;
···147156 '';
148157149158 };
159159+160160+ /* For configurations of Elixir project, like config.exs or runtime.exs
161161+162162+ Most Elixir project are configured using the [Config] Elixir DSL
163163+164164+ Since Elixir has more types than Nix, we need a way to map Nix types to
165165+ more than 1 Elixir type. To that end, this format provides its own library,
166166+ and its own set of types.
167167+168168+ To be more detailed, a Nix attribute set could correspond in Elixir to a
169169+ [Keyword list] (the more common type), or it could correspond to a [Map].
170170+171171+ A Nix string could correspond in Elixir to a [String] (also called
172172+ "binary"), an [Atom], or a list of chars (usually discouraged).
173173+174174+ A Nix array could correspond in Elixir to a [List] or a [Tuple].
175175+176176+ Some more types exists, like records, regexes, but since they are less used,
177177+ we can leave the `mkRaw` function as an escape hatch.
178178+179179+ For more information on how to use this format in modules, please refer to
180180+ the Elixir section of the Nixos documentation.
181181+182182+ TODO: special Elixir values doesn't show up nicely in the documentation
183183+184184+ [Config]: <https://hexdocs.pm/elixir/Config.html>
185185+ [Keyword list]: <https://hexdocs.pm/elixir/Keyword.html>
186186+ [Map]: <https://hexdocs.pm/elixir/Map.html>
187187+ [String]: <https://hexdocs.pm/elixir/String.html>
188188+ [Atom]: <https://hexdocs.pm/elixir/Atom.html>
189189+ [List]: <https://hexdocs.pm/elixir/List.html>
190190+ [Tuple]: <https://hexdocs.pm/elixir/Tuple.html>
191191+ */
192192+ elixirConf = { elixir ? pkgs.elixir }:
193193+ with lib; let
194194+ toElixir = value: with builtins;
195195+ if value == null then "nil" else
196196+ if value == true then "true" else
197197+ if value == false then "false" else
198198+ if isInt value || isFloat value then toString value else
199199+ if isString value then string value else
200200+ if isAttrs value then attrs value else
201201+ if isList value then list value else
202202+ abort "formats.elixirConf: should never happen (value = ${value})";
203203+204204+ escapeElixir = escape [ "\\" "#" "\"" ];
205205+ string = value: "\"${escapeElixir value}\"";
206206+207207+ attrs = set:
208208+ if set ? _elixirType then specialType set
209209+ else
210210+ let
211211+ toKeyword = name: value: "${name}: ${toElixir value}";
212212+ keywordList = concatStringsSep ", " (mapAttrsToList toKeyword set);
213213+ in
214214+ "[" + keywordList + "]";
215215+216216+ listContent = values: concatStringsSep ", " (map toElixir values);
217217+218218+ list = values: "[" + (listContent values) + "]";
219219+220220+ specialType = { value, _elixirType }:
221221+ if _elixirType == "raw" then value else
222222+ if _elixirType == "atom" then value else
223223+ if _elixirType == "map" then elixirMap value else
224224+ if _elixirType == "tuple" then tuple value else
225225+ abort "formats.elixirConf: should never happen (_elixirType = ${_elixirType})";
226226+227227+ elixirMap = set:
228228+ let
229229+ toEntry = name: value: "${toElixir name} => ${toElixir value}";
230230+ entries = concatStringsSep ", " (mapAttrsToList toEntry set);
231231+ in
232232+ "%{${entries}}";
233233+234234+ tuple = values: "{${listContent values}}";
235235+236236+ toConf = values:
237237+ let
238238+ keyConfig = rootKey: key: value:
239239+ "config ${rootKey}, ${key}, ${toElixir value}";
240240+ keyConfigs = rootKey: values: mapAttrsToList (keyConfig rootKey) values;
241241+ rootConfigs = flatten (mapAttrsToList keyConfigs values);
242242+ in
243243+ ''
244244+ import Config
245245+246246+ ${concatStringsSep "\n" rootConfigs}
247247+ '';
248248+ in
249249+ {
250250+ type = with lib.types; let
251251+ valueType = nullOr
252252+ (oneOf [
253253+ bool
254254+ int
255255+ float
256256+ str
257257+ (attrsOf valueType)
258258+ (listOf valueType)
259259+ ]) // {
260260+ description = "Elixir value";
261261+ };
262262+ in
263263+ attrsOf (attrsOf (valueType));
264264+265265+ lib =
266266+ let
267267+ mkRaw = value: {
268268+ inherit value;
269269+ _elixirType = "raw";
270270+ };
271271+272272+ in
273273+ {
274274+ inherit mkRaw;
275275+276276+ /* Fetch an environment variable at runtime, with optional fallback
277277+ */
278278+ mkGetEnv = { envVariable, fallback ? null }:
279279+ mkRaw "System.get_env(${toElixir envVariable}, ${toElixir fallback})";
280280+281281+ /* Make an Elixir atom.
282282+283283+ Note: lowercase atoms still need to be prefixed by ':'
284284+ */
285285+ mkAtom = value: {
286286+ inherit value;
287287+ _elixirType = "atom";
288288+ };
289289+290290+ /* Make an Elixir tuple out of a list.
291291+ */
292292+ mkTuple = value: {
293293+ inherit value;
294294+ _elixirType = "tuple";
295295+ };
296296+297297+ /* Make an Elixir map out of an attribute set.
298298+ */
299299+ mkMap = value: {
300300+ inherit value;
301301+ _elixirType = "map";
302302+ };
303303+304304+ /* Contains Elixir types. Every type it exports can also be replaced
305305+ by raw Elixir code (i.e. every type is `either type rawElixir`).
306306+307307+ It also reexports standard types, wrapping them so that they can
308308+ also be raw Elixir.
309309+ */
310310+ types = with lib.types; let
311311+ isElixirType = type: x: (x._elixirType or "") == type;
312312+313313+ rawElixir = mkOptionType {
314314+ name = "rawElixir";
315315+ description = "raw elixir";
316316+ check = isElixirType "raw";
317317+ };
318318+319319+ elixirOr = other: either other rawElixir;
320320+ in
321321+ {
322322+ inherit rawElixir elixirOr;
323323+324324+ atom = elixirOr (mkOptionType {
325325+ name = "elixirAtom";
326326+ description = "elixir atom";
327327+ check = isElixirType "atom";
328328+ });
329329+330330+ tuple = elixirOr (mkOptionType {
331331+ name = "elixirTuple";
332332+ description = "elixir tuple";
333333+ check = isElixirType "tuple";
334334+ });
335335+336336+ map = elixirOr (mkOptionType {
337337+ name = "elixirMap";
338338+ description = "elixir map";
339339+ check = isElixirType "map";
340340+ });
341341+ # Wrap standard types, since anything in the Elixir configuration
342342+ # can be raw Elixir
343343+ } // lib.mapAttrs (_name: type: elixirOr type) lib.types;
344344+ };
345345+346346+ generate = name: value: pkgs.runCommandNoCC name
347347+ {
348348+ value = toConf value;
349349+ passAsFile = [ "value" ];
350350+ nativeBuildInputs = [ elixir ];
351351+ } ''
352352+ cp "$valuePath" "$out"
353353+ mix format "$out"
354354+ '';
355355+ };
356356+150357}