diff --git a/modules/misc/news.nix b/modules/misc/news.nix
index 3bb9ce80b..9a77dee87 100644
--- a/modules/misc/news.nix
+++ b/modules/misc/news.nix
@@ -107,6 +107,15 @@ in
config = {
news.entries = [
+ {
+ time = "2017-09-10T22:15:19+00:00";
+ condition = config.programs.zsh.enable;
+ message = ''
+ Home Manager now offers its own minimal zsh plugin manager
+ under the 'programs.zsh.plugins' option path. By statically
+ sourcing your plugins it achieves no startup overhead.
+ '';
+ }
{
time = "2017-09-01T10:56:28+00:00";
message = ''
diff --git a/modules/programs/zsh.nix b/modules/programs/zsh.nix
index be9eb3c73..26de2b449 100644
--- a/modules/programs/zsh.nix
+++ b/modules/programs/zsh.nix
@@ -37,6 +37,36 @@ let
};
};
+ pluginModule = types.submodule ({ config, ... }: {
+ options = {
+ src = mkOption {
+ type = types.path;
+ description = ''
+ Path to the plugin folder.
+
+ Will be added to fpath and PATH.
+ '';
+ };
+
+ name = mkOption {
+ type = types.str;
+ description = ''
+ The name of the plugin.
+
+ Don't forget to add
+ if the script name does not follow convention.
+ '';
+ };
+
+ file = mkOption {
+ type = types.str;
+ description = "The plugin script to source.";
+ };
+ };
+
+ config.file = mkDefault "${config.name}.plugin.zsh";
+ });
+
in
{
@@ -74,13 +104,43 @@ in
initExtra = mkOption {
default = "";
type = types.lines;
- description = "Extra commands that should be added to .zshrc.";
+ description = "Extra commands that should be added to .zshrc.";
+ };
+
+ plugins = mkOption {
+ type = types.listOf pluginModule;
+ default = [];
+ example = literalExample ''
+ [
+ {
+ # will source zsh-autosuggestions.plugin.zsh
+ name = "zsh-autosuggestions";
+ src = pkgs.fetchFromGitHub {
+ owner = "zsh-users";
+ repo = "zsh-autosuggestions";
+ rev = "v0.4.0";
+ sha256 = "0z6i9wjjklb4lvr7zjhbphibsyx51psv50gm07mbb0kj9058j6kc";
+ };
+ }
+ {
+ name = "enhancd";
+ file = "init.sh";
+ src = pkgs.fetchFromGitHub {
+ owner = "b4b4r07";
+ repo = "enhancd";
+ rev = "v2.2.1";
+ sha256 = "0iqa9j09fwm6nj5rpip87x3hnvbbz9w9ajgm6wkrd5fls8fn8i5g";
+ };
+ }
+ ]
+ '';
+ description = "Plugins to source in .zshrc.";
};
};
};
- config = (
- let
+ config = mkMerge [
+ (let
aliasesStr = concatStringsSep "\n" (
mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases
);
@@ -109,15 +169,34 @@ in
HELPDIR="${pkgs.zsh}/share/zsh/$ZSH_VERSION/help"
- ${if cfg.enableCompletion then "autoload -U compinit && compinit" else ""}
+ ${concatStrings (map (plugin: ''
+ path+="$HOME/.zsh/plugins/${plugin.name}"
+ fpath+="$HOME/.zsh/plugins/${plugin.name}"
+ '') cfg.plugins)}
+
+ ${optionalString cfg.enableCompletion "autoload -U compinit && compinit"}
${optionalString (cfg.enableAutosuggestions)
"source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh"
}
+ ${concatStrings (map (plugin: ''
+ source "$HOME/.zsh/plugins/${plugin.name}/${plugin.file}"
+ '') cfg.plugins)}
+
${aliasesStr}
${cfg.initExtra}
'';
- }
- );
+ })
+ (mkIf (cfg.plugins != []) {
+ # Many plugins require compinit to be called
+ # but allow the user to opt out.
+ programs.zsh.enableCompletion = mkDefault true;
+
+ home.file = map (plugin: {
+ target = ".zsh/plugins/${plugin.name}";
+ source = plugin.src;
+ }) cfg.plugins;
+ })
+ ];
}