at master 9.3 kB view raw
1# This module defines global configuration for the zshell. 2 3{ 4 config, 5 lib, 6 options, 7 pkgs, 8 ... 9}: 10 11let 12 13 cfge = config.environment; 14 15 cfg = config.programs.zsh; 16 opt = options.programs.zsh; 17 18 zshAliases = builtins.concatStringsSep "\n" ( 19 lib.mapAttrsToList (k: v: "alias -- ${k}=${lib.escapeShellArg v}") ( 20 lib.filterAttrs (k: v: v != null) cfg.shellAliases 21 ) 22 ); 23 24 zshStartupNotes = '' 25 # Note that generated /etc/zprofile and /etc/zshrc files do a lot of 26 # non-standard setup to make zsh usable with no configuration by default. 27 # 28 # Which means that unless you explicitly meticulously override everything 29 # generated, interactions between your ~/.zshrc and these files are likely 30 # to be rather surprising. 31 # 32 # Note however, that you can disable loading of the generated /etc/zprofile 33 # and /etc/zshrc (you can't disable loading of /etc/zshenv, but it is 34 # designed to not set anything surprising) by setting `no_global_rcs` option 35 # in ~/.zshenv: 36 # 37 # echo setopt no_global_rcs >> ~/.zshenv 38 # 39 # See "STARTUP/SHUTDOWN FILES" section of zsh(1) for more info. 40 ''; 41 42in 43 44{ 45 46 options = { 47 48 programs.zsh = { 49 50 enable = lib.mkOption { 51 default = false; 52 description = '' 53 Whether to configure zsh as an interactive shell. To enable zsh for 54 a particular user, use the {option}`users.users.<name?>.shell` 55 option for that user. To enable zsh system-wide use the 56 {option}`users.defaultUserShell` option. 57 ''; 58 type = lib.types.bool; 59 }; 60 61 shellAliases = lib.mkOption { 62 default = { }; 63 description = '' 64 Set of aliases for zsh shell, which overrides {option}`environment.shellAliases`. 65 See {option}`environment.shellAliases` for an option format description. 66 ''; 67 type = with lib.types; attrsOf (nullOr (either str path)); 68 }; 69 70 shellInit = lib.mkOption { 71 default = ""; 72 description = '' 73 Shell script code called during zsh shell initialisation. 74 ''; 75 type = lib.types.lines; 76 }; 77 78 loginShellInit = lib.mkOption { 79 default = ""; 80 description = '' 81 Shell script code called during zsh login shell initialisation. 82 ''; 83 type = lib.types.lines; 84 }; 85 86 interactiveShellInit = lib.mkOption { 87 default = ""; 88 description = '' 89 Shell script code called during interactive zsh shell initialisation. 90 ''; 91 type = lib.types.lines; 92 }; 93 94 promptInit = lib.mkOption { 95 default = '' 96 # Note that to manually override this in ~/.zshrc you should run `prompt off` 97 # before setting your PS1 and etc. Otherwise this will likely to interact with 98 # your ~/.zshrc configuration in unexpected ways as the default prompt sets 99 # a lot of different prompt variables. 100 autoload -U promptinit && promptinit && prompt suse && setopt prompt_sp 101 ''; 102 description = '' 103 Shell script code used to initialise the zsh prompt. 104 ''; 105 type = lib.types.lines; 106 }; 107 108 histSize = lib.mkOption { 109 default = 2000; 110 description = '' 111 Change history size. 112 ''; 113 type = lib.types.int; 114 }; 115 116 histFile = lib.mkOption { 117 default = "$HOME/.zsh_history"; 118 description = '' 119 Change history file. 120 ''; 121 type = lib.types.str; 122 }; 123 124 setOptions = lib.mkOption { 125 type = lib.types.listOf lib.types.str; 126 default = [ 127 "HIST_IGNORE_DUPS" 128 "SHARE_HISTORY" 129 "HIST_FCNTL_LOCK" 130 ]; 131 example = [ 132 "EXTENDED_HISTORY" 133 "RM_STAR_WAIT" 134 ]; 135 description = '' 136 Configure zsh options. See 137 {manpage}`zshoptions(1)`. 138 ''; 139 }; 140 141 enableCompletion = lib.mkOption { 142 default = true; 143 description = '' 144 Enable zsh completion for all interactive zsh shells. 145 ''; 146 type = lib.types.bool; 147 }; 148 149 enableBashCompletion = lib.mkOption { 150 default = false; 151 description = '' 152 Enable compatibility with bash's programmable completion system. 153 ''; 154 type = lib.types.bool; 155 }; 156 157 enableGlobalCompInit = lib.mkOption { 158 default = cfg.enableCompletion; 159 defaultText = lib.literalExpression "config.${opt.enableCompletion}"; 160 description = '' 161 Enable execution of compinit call for all interactive zsh shells. 162 163 This option can be disabled if the user wants to extend its 164 `fpath` and a custom `compinit` 165 call in the local config is required. 166 ''; 167 type = lib.types.bool; 168 }; 169 170 enableLsColors = lib.mkOption { 171 default = true; 172 description = '' 173 Enable extra colors in directory listings (used by `ls` and `tree`). 174 ''; 175 type = lib.types.bool; 176 }; 177 178 }; 179 180 }; 181 182 config = lib.mkIf cfg.enable { 183 184 programs.zsh.shellAliases = builtins.mapAttrs (name: lib.mkDefault) cfge.shellAliases; 185 186 environment.etc.zshenv.text = '' 187 # /etc/zshenv: DO NOT EDIT -- this file has been generated automatically. 188 # This file is read for all shells. 189 190 # Only execute this file once per shell. 191 if [ -n "''${__ETC_ZSHENV_SOURCED-}" ]; then return; fi 192 __ETC_ZSHENV_SOURCED=1 193 194 if [ -z "''${__NIXOS_SET_ENVIRONMENT_DONE-}" ]; then 195 . ${config.system.build.setEnvironment} 196 fi 197 198 HELPDIR="${pkgs.zsh}/share/zsh/$ZSH_VERSION/help" 199 200 # Tell zsh how to find installed completions. 201 for p in ''${(z)NIX_PROFILES}; do 202 fpath=($p/share/zsh/site-functions $p/share/zsh/$ZSH_VERSION/functions $p/share/zsh/vendor-completions $fpath) 203 done 204 205 # Setup custom shell init stuff. 206 ${cfge.shellInit} 207 208 ${cfg.shellInit} 209 210 # Read system-wide modifications. 211 if test -f /etc/zshenv.local; then 212 . /etc/zshenv.local 213 fi 214 ''; 215 216 environment.etc.zprofile.text = '' 217 # /etc/zprofile: DO NOT EDIT -- this file has been generated automatically. 218 # This file is read for login shells. 219 # 220 ${zshStartupNotes} 221 222 # Only execute this file once per shell. 223 if [ -n "''${__ETC_ZPROFILE_SOURCED-}" ]; then return; fi 224 __ETC_ZPROFILE_SOURCED=1 225 226 # Setup custom login shell init stuff. 227 ${cfge.loginShellInit} 228 229 ${cfg.loginShellInit} 230 231 # Read system-wide modifications. 232 if test -f /etc/zprofile.local; then 233 . /etc/zprofile.local 234 fi 235 ''; 236 237 environment.etc.zshrc.text = '' 238 # /etc/zshrc: DO NOT EDIT -- this file has been generated automatically. 239 # This file is read for interactive shells. 240 # 241 ${zshStartupNotes} 242 243 # Only execute this file once per shell. 244 if [ -n "$__ETC_ZSHRC_SOURCED" -o -n "$NOSYSZSHRC" ]; then return; fi 245 __ETC_ZSHRC_SOURCED=1 246 247 ${lib.optionalString (cfg.setOptions != [ ]) '' 248 # Set zsh options. 249 setopt ${builtins.concatStringsSep " " cfg.setOptions} 250 ''} 251 252 # Alternative method of determining short and full hostname. 253 HOST=${config.networking.fqdnOrHostName} 254 255 # Setup command line history. 256 # Don't export these, otherwise other shells (bash) will try to use same HISTFILE. 257 SAVEHIST=${builtins.toString cfg.histSize} 258 HISTSIZE=${builtins.toString cfg.histSize} 259 HISTFILE=${cfg.histFile} 260 261 # Configure sane keyboard defaults. 262 . /etc/zinputrc 263 264 ${lib.optionalString cfg.enableGlobalCompInit '' 265 # Enable autocompletion. 266 autoload -U compinit && compinit 267 ''} 268 269 ${lib.optionalString cfg.enableBashCompletion '' 270 # Enable compatibility with bash's completion system. 271 autoload -U bashcompinit && bashcompinit 272 ''} 273 274 # Setup custom interactive shell init stuff. 275 ${cfge.interactiveShellInit} 276 277 ${cfg.interactiveShellInit} 278 279 ${lib.optionalString cfg.enableLsColors '' 280 # Extra colors for directory listings. 281 eval "$(${pkgs.coreutils}/bin/dircolors -b)" 282 ''} 283 284 # Setup aliases. 285 ${zshAliases} 286 287 # Setup prompt. 288 ${cfg.promptInit} 289 290 # Disable some features to support TRAMP. 291 if [ "$TERM" = dumb ]; then 292 unsetopt zle prompt_cr prompt_subst 293 unset RPS1 RPROMPT 294 PS1='$ ' 295 PROMPT='$ ' 296 fi 297 298 # Read system-wide modifications. 299 if test -f /etc/zshrc.local; then 300 . /etc/zshrc.local 301 fi 302 ''; 303 304 # Bug in nix flakes: 305 # If we use `.source` here the path is garbage collected also we point to it with a symlink 306 # see https://github.com/NixOS/nixpkgs/issues/132732 307 environment.etc.zinputrc.text = builtins.readFile ./zinputrc; 308 309 environment.systemPackages = [ 310 pkgs.zsh 311 ] 312 ++ lib.optional cfg.enableCompletion pkgs.nix-zsh-completions; 313 314 environment.pathsToLink = lib.optional cfg.enableCompletion "/share/zsh"; 315 316 #users.defaultUserShell = lib.mkDefault "/run/current-system/sw/bin/zsh"; 317 318 environment.shells = [ 319 "/run/current-system/sw/bin/zsh" 320 "${pkgs.zsh}/bin/zsh" 321 ]; 322 323 }; 324 325}