{ config, lib, pkgs, ... }: with lib; let cfg = config.programs.zsh; in { options = { programs.zsh = { enable = mkEnableOption "Z shell (Zsh)"; historySize = mkOption { type = types.int; default = 10000; description = "Number of history lines to keep."; }; shellAliases = mkOption { default = {}; example = { ll = "ls -l"; ".." = "cd .."; }; description = '' An attribute set that maps aliases (the top level attribute names in this option) to command strings or directly to build outputs. ''; type = types.attrs; }; enableCompletion = mkOption { default = true; description = '' Enable zsh completion. ''; type = types.bool; }; enableAutosuggestions = mkOption { default = false; description = '' Enable zsh autosuggestions ''; }; profileExtra = mkOption { default = ""; type = types.lines; description = "Extra commands that should be added to .zprofile."; }; initExtra = mkOption { default = ""; type = types.lines; description = "Extra commands that should be added to .zshrc."; }; }; }; config = ( let aliasesStr = concatStringsSep "\n" ( mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases ); export = n: v: "export ${n}=\"${toString v}\""; exportIfNonNull = n: v: optionalString (v != null) (export n v); exportIfNonEmpty = n: v: optionalString (v != "") (export n v); histControlStr = concatStringsSep ":" cfg.historyControl; histIgnoreStr = concatStringsSep ":" cfg.historyIgnore; envVarsStr = concatStringsSep "\n" ( mapAttrsToList export config.home.sessionVariables ); in mkIf cfg.enable { home.packages = [ pkgs.zsh ] ++ optional cfg.enableCompletion pkgs.nix-zsh-completions; home.file.".zprofile".text = '' ${optionalString (config.home.sessionVariableSetter == "zsh") envVarsStr} ${cfg.profileExtra} ''; home.file.".zshrc".text = '' ${export "HISTSIZE" cfg.historySize} ${if cfg.enableCompletion then "autoload -U compinit && compinit" else ""} ${optionalString (cfg.enableAutosuggestions) "source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh" } ${aliasesStr} ${cfg.initExtra} ''; } ); }