1<chapter xmlns="http://docbook.org/ns/docbook"
2 xmlns:xlink="http://www.w3.org/1999/xlink"
3 xmlns:xi="http://www.w3.org/2001/XInclude"
4 version="5.0"
5 xml:id="module-programs-zsh-ohmyzsh">
6
7<title>Oh my ZSH</title>
8
9<para><literal><link xlink:href="https://ohmyz.sh/">oh-my-zsh</link></literal> is a framework
10to manage your <link xlink:href="https://www.zsh.org/">ZSH</link> configuration
11including completion scripts for several CLI tools or custom prompt themes.</para>
12
13<section xml:id="module-programs-oh-my-zsh-usage"><title>Basic usage</title>
14<para>The module uses the <literal>oh-my-zsh</literal> package with all available features. The
15initial setup using Nix expressions is fairly similar to the configuration format
16of <literal>oh-my-zsh</literal>.
17
18<programlisting>
19{
20 programs.ohMyZsh = {
21 enable = true;
22 plugins = [ "git" "python" "man" ];
23 theme = "agnoster";
24 };
25}
26</programlisting>
27
28For a detailed explanation of these arguments please refer to the
29<link xlink:href="https://github.com/robbyrussell/oh-my-zsh/wiki"><literal>oh-my-zsh</literal> docs</link>.
30</para>
31<para>The expression generates the needed
32configuration and writes it into your <literal>/etc/zshrc</literal>.
33</para></section>
34
35<section xml:id="module-programs-oh-my-zsh-additions"><title>Custom additions</title>
36
37<para>Sometimes third-party or custom scripts such as a modified theme may be needed.
38<literal>oh-my-zsh</literal> provides the
39<link xlink:href="https://github.com/robbyrussell/oh-my-zsh/wiki/Customization#overriding-internals"><literal>ZSH_CUSTOM</literal></link>
40environment variable for this which points to a directory with additional scripts.</para>
41
42<para>The module can do this as well:
43
44<programlisting>
45{
46 programs.ohMyZsh.custom = "~/path/to/custom/scripts";
47}
48</programlisting>
49</para></section>
50
51<section xml:id="module-programs-oh-my-zsh-environments"><title>Custom environments</title>
52
53<para>There are several extensions for <literal>oh-my-zsh</literal> packaged in <literal>nixpkgs</literal>.
54One of them is <link xlink:href="https://github.com/spwhitt/nix-zsh-completions">nix-zsh-completions</link>
55which bundles completion scripts and a plugin for <literal>oh-my-zsh</literal>.</para>
56
57<para>Rather than using a single mutable path for <literal>ZSH_CUSTOM</literal>, it's also possible to
58generate this path from a list of Nix packages:
59
60<programlisting>
61{ pkgs, ... }:
62{
63 programs.ohMyZsh.customPkgs = with pkgs; [
64 pkgs.nix-zsh-completions
65 # and even more...
66 ];
67}
68</programlisting>
69
70Internally a single store path will be created using <literal>buildEnv</literal>.
71Please refer to the docs of
72<link xlink:href="https://nixos.org/nixpkgs/manual/#sec-building-environment"><literal>buildEnv</literal></link>
73for further reference.</para>
74
75<para><emphasis>Please keep in mind that this is not compatible with <literal>programs.ohMyZsh.custom</literal>
76as it requires an immutable store path while <literal>custom</literal> shall remain mutable! An evaluation failure
77will be thrown if both <literal>custom</literal> and <literal>customPkgs</literal> are set.</emphasis>
78</para></section>
79
80<section xml:id="module-programs-oh-my-zsh-packaging-customizations"><title>Package your own customizations</title>
81
82<para>If third-party customizations (e.g. new themes) are supposed to be added to <literal>oh-my-zsh</literal>
83there are several pitfalls to keep in mind:</para>
84
85<itemizedlist>
86 <listitem>
87 <para>To comply with the default structure of <literal>ZSH</literal> the entire output needs to be written to
88 <literal>$out/share/zsh.</literal></para>
89 </listitem>
90 <listitem>
91 <para>Completion scripts are supposed to be stored at <literal>$out/share/zsh/site-functions</literal>. This directory
92 is part of the <literal><link xlink:href="http://zsh.sourceforge.net/Doc/Release/Functions.html">fpath</link></literal>
93 and the package should be compatible with pure <literal>ZSH</literal> setups. The module will automatically link
94 the contents of <literal>site-functions</literal> to completions directory in the proper store path.</para>
95 </listitem>
96 <listitem>
97 <para>The <literal>plugins</literal> directory needs the structure <literal>pluginname/pluginname.plugin.zsh</literal>
98 as structured in the <link xlink:href="https://github.com/robbyrussell/oh-my-zsh/tree/91b771914bc7c43dd7c7a43b586c5de2c225ceb7/plugins">upstream repo.</link>
99 </para>
100 </listitem>
101</itemizedlist>
102
103<para>
104A derivation for <literal>oh-my-zsh</literal> may look like this:
105<programlisting>
106{ stdenv, fetchFromGitHub }:
107
108stdenv.mkDerivation rec {
109 name = "exemplary-zsh-customization-${version}";
110 version = "1.0.0";
111 src = fetchFromGitHub {
112 # path to the upstream repository
113 };
114
115 dontBuild = true;
116 installPhase = ''
117 mkdir -p $out/share/zsh/site-functions
118 cp {themes,plugins} $out/share/zsh
119 cp completions $out/share/zsh/site-functions
120 '';
121}
122</programlisting>
123</para>
124</section>
125</chapter>