1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.programs.zsh.ohMyZsh;
8
9 mkLinkFarmEntry = name: dir:
10 let
11 env = pkgs.buildEnv {
12 name = "zsh-${name}-env";
13 paths = cfg.customPkgs;
14 pathsToLink = "/share/zsh/${dir}";
15 };
16 in
17 { inherit name; path = "${env}/share/zsh/${dir}"; };
18
19 mkLinkFarmEntry' = name: mkLinkFarmEntry name name;
20
21 custom =
22 if cfg.custom != null then cfg.custom
23 else if length cfg.customPkgs == 0 then null
24 else pkgs.linkFarm "oh-my-zsh-custom" [
25 (mkLinkFarmEntry' "themes")
26 (mkLinkFarmEntry "completions" "site-functions")
27 (mkLinkFarmEntry' "plugins")
28 ];
29
30in
31 {
32 imports = [
33 (mkRenamedOptionModule [ "programs" "zsh" "oh-my-zsh" "enable" ] [ "programs" "zsh" "ohMyZsh" "enable" ])
34 (mkRenamedOptionModule [ "programs" "zsh" "oh-my-zsh" "theme" ] [ "programs" "zsh" "ohMyZsh" "theme" ])
35 (mkRenamedOptionModule [ "programs" "zsh" "oh-my-zsh" "custom" ] [ "programs" "zsh" "ohMyZsh" "custom" ])
36 (mkRenamedOptionModule [ "programs" "zsh" "oh-my-zsh" "plugins" ] [ "programs" "zsh" "ohMyZsh" "plugins" ])
37 ];
38
39 options = {
40 programs.zsh.ohMyZsh = {
41 enable = mkOption {
42 type = types.bool;
43 default = false;
44 description = lib.mdDoc ''
45 Enable oh-my-zsh.
46 '';
47 };
48
49 package = mkOption {
50 default = pkgs.oh-my-zsh;
51 defaultText = literalExpression "pkgs.oh-my-zsh";
52 description = lib.mdDoc ''
53 Package to install for `oh-my-zsh` usage.
54 '';
55
56 type = types.package;
57 };
58
59 plugins = mkOption {
60 default = [];
61 type = types.listOf(types.str);
62 description = lib.mdDoc ''
63 List of oh-my-zsh plugins
64 '';
65 };
66
67 custom = mkOption {
68 default = null;
69 type = with types; nullOr str;
70 description = lib.mdDoc ''
71 Path to a custom oh-my-zsh package to override config of oh-my-zsh.
72 (Can't be used along with `customPkgs`).
73 '';
74 };
75
76 customPkgs = mkOption {
77 default = [];
78 type = types.listOf types.package;
79 description = lib.mdDoc ''
80 List of custom packages that should be loaded into `oh-my-zsh`.
81 '';
82 };
83
84 theme = mkOption {
85 default = "";
86 type = types.str;
87 description = lib.mdDoc ''
88 Name of the theme to be used by oh-my-zsh.
89 '';
90 };
91
92 cacheDir = mkOption {
93 default = "$HOME/.cache/oh-my-zsh";
94 type = types.str;
95 description = lib.mdDoc ''
96 Cache directory to be used by `oh-my-zsh`.
97 Without this option it would default to the read-only nix store.
98 '';
99 };
100 };
101 };
102
103 config = mkIf cfg.enable {
104
105 # Prevent zsh from overwriting oh-my-zsh's prompt
106 programs.zsh.promptInit = mkDefault "";
107
108 environment.systemPackages = [ cfg.package ];
109
110 programs.zsh.interactiveShellInit = ''
111 # oh-my-zsh configuration generated by NixOS
112 export ZSH=${cfg.package}/share/oh-my-zsh
113
114 ${optionalString (length(cfg.plugins) > 0)
115 "plugins=(${concatStringsSep " " cfg.plugins})"
116 }
117
118 ${optionalString (custom != null)
119 "ZSH_CUSTOM=\"${custom}\""
120 }
121
122 ${optionalString (stringLength(cfg.theme) > 0)
123 "ZSH_THEME=\"${cfg.theme}\""
124 }
125
126 ${optionalString (cfg.cacheDir != null) ''
127 if [[ ! -d "${cfg.cacheDir}" ]]; then
128 mkdir -p "${cfg.cacheDir}"
129 fi
130 ZSH_CACHE_DIR=${cfg.cacheDir}
131 ''}
132
133 source $ZSH/oh-my-zsh.sh
134 '';
135
136 assertions = [
137 {
138 assertion = cfg.custom != null -> cfg.customPkgs == [];
139 message = "If `cfg.custom` is set for `ZSH_CUSTOM`, `customPkgs` can't be used!";
140 }
141 ];
142
143 };
144
145 meta.doc = ./oh-my-zsh.md;
146 }