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