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