diff --git a/modules/default.nix b/modules/default.nix index 0b163c7d2..4206fa938 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -26,6 +26,7 @@ let ./programs/lesspipe.nix ./programs/ssh.nix ./programs/texlive.nix + ./programs/zsh.nix ./services/dunst.nix ./services/gnome-keyring.nix ./services/gpg-agent.nix diff --git a/modules/home-environment.nix b/modules/home-environment.nix index 6596a1162..bd2fb6ffa 100644 --- a/modules/home-environment.nix +++ b/modules/home-environment.nix @@ -165,7 +165,7 @@ in home.sessionVariableSetter = mkOption { default = "bash"; - type = types.enum [ "pam" "bash" ]; + type = types.enum [ "pam" "bash" "zsh" ]; example = "pam"; description = '' Identifies the module that should set the session variables. diff --git a/modules/programs/zsh.nix b/modules/programs/zsh.nix new file mode 100644 index 000000000..b0c528e57 --- /dev/null +++ b/modules/programs/zsh.nix @@ -0,0 +1,102 @@ +{ 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} + ''; + } + ); +}