diff --git a/nixos/modules/programs/zsh/oh-my-zsh.nix b/nixos/modules/programs/zsh/oh-my-zsh.nix index b995d390b279..f4df4e983e42 100644 --- a/nixos/modules/programs/zsh/oh-my-zsh.nix +++ b/nixos/modules/programs/zsh/oh-my-zsh.nix @@ -3,7 +3,30 @@ with lib; let + cfg = config.programs.zsh.ohMyZsh; + + mkLinkFarmEntry = name: dir: + let + env = pkgs.buildEnv { + name = "zsh-${name}-env"; + paths = cfg.customPkgs; + pathsToLink = "/share/zsh/${dir}"; + }; + in + { inherit name; path = "${env}/share/zsh/${dir}"; }; + + mkLinkFarmEntry' = name: mkLinkFarmEntry name name; + + custom = + if cfg.custom != null then cfg.custom + else if length cfg.customPkgs == 0 then null + else pkgs.linkFarm "oh-my-zsh-custom" [ + (mkLinkFarmEntry' "themes") + (mkLinkFarmEntry "completions" "site-functions") + (mkLinkFarmEntry' "plugins") + ]; + in { options = { @@ -34,10 +57,19 @@ in }; custom = mkOption { - default = ""; - type = types.str; + default = null; + type = with types; nullOr str; description = '' Path to a custom oh-my-zsh package to override config of oh-my-zsh. + (Can't be used along with `customPkgs`). + ''; + }; + + customPkgs = mkOption { + default = []; + type = types.listOf types.package; + description = '' + List of custom packages that should be loaded into `oh-my-zsh`. ''; }; @@ -67,7 +99,7 @@ in environment.systemPackages = [ cfg.package ]; - programs.zsh.interactiveShellInit = with builtins; '' + programs.zsh.interactiveShellInit = '' # oh-my-zsh configuration generated by NixOS export ZSH=${cfg.package}/share/oh-my-zsh @@ -75,8 +107,8 @@ in "plugins=(${concatStringsSep " " cfg.plugins})" } - ${optionalString (stringLength(cfg.custom) > 0) - "ZSH_CUSTOM=\"${cfg.custom}\"" + ${optionalString (custom != null) + "ZSH_CUSTOM=\"${custom}\"" } ${optionalString (stringLength(cfg.theme) > 0) @@ -92,5 +124,15 @@ in source $ZSH/oh-my-zsh.sh ''; + + assertions = [ + { + assertion = cfg.custom != null -> cfg.customPkgs == []; + message = "If `cfg.custom` is set for `ZSH_CUSTOM`, `customPkgs` can't be used!"; + } + ]; + }; + + meta.doc = ./oh-my-zsh.xml; } diff --git a/nixos/modules/programs/zsh/oh-my-zsh.xml b/nixos/modules/programs/zsh/oh-my-zsh.xml new file mode 100644 index 000000000000..b74da8630ee7 --- /dev/null +++ b/nixos/modules/programs/zsh/oh-my-zsh.xml @@ -0,0 +1,125 @@ + + +Oh my ZSH + +oh-my-zsh is a framework +to manage your ZSH configuration +including completion scripts for several CLI tools or custom prompt themes. + +
Basic usage +The module uses the oh-my-zsh package with all available features. The +initial setup using Nix expressions is fairly similar to the configuration format +of oh-my-zsh. + + +{ + programs.ohMyZsh = { + enable = true; + plugins = [ "git" "python" "man" ]; + theme = "agnoster"; + }; +} + + +For a detailed explanation of these arguments please refer to the +oh-my-zsh docs. + +The expression generates the needed +configuration and writes it into your /etc/zshrc. +
+ +
Custom additions + +Sometimes third-party or custom scripts such as a modified theme may be needed. +oh-my-zsh provides the +ZSH_CUSTOM +environment variable for this which points to a directory with additional scripts. + +The module can do this as well: + + +{ + programs.ohMyZsh.custom = "~/path/to/custom/scripts"; +} + +
+ +
Custom environments + +There are several extensions for oh-my-zsh packaged in nixpkgs. +One of them is nix-zsh-completions +which bundles completion scripts and a plugin for oh-my-zsh. + +Rather than using a single mutable path for ZSH_CUSTOM, it's also possible to +generate this path from a list of Nix packages: + + +{ pkgs, ... }: +{ + programs.ohMyZsh.customPkgs = with pkgs; [ + pkgs.nix-zsh-completions + # and even more... + ]; +} + + +Internally a single store path will be created using buildEnv. +Please refer to the docs of +buildEnv +for further reference. + +Please keep in mind that this is not compatible with programs.ohMyZsh.custom +as it requires an immutable store path while custom shall remain mutable! An evaluation failure +will be thrown if both custom and customPkgs are set. +
+ +
Package your own customizations + +If third-party customizations (e.g. new themes) are supposed to be added to oh-my-zsh +there are several pitfalls to keep in mind: + + + + To comply with the default structure of ZSH the entire output needs to be written to + $out/share/zsh. + + + Completion scripts are supposed to be stored at $out/share/zsh/site-functions. This directory + is part of the fpath + and the package should be compatible with pure ZSH setups. The module will automatically link + the contents of site-functions to completions directory in the proper store path. + + + The plugins directory needs the structure pluginname/pluginname.plugin.zsh + as structured in the upstream repo. + + + + + +A derivation for oh-my-zsh may look like this: + +{ stdenv, fetchFromGitHub }: + +stdenv.mkDerivation rec { + name = "exemplary-zsh-customization-${version}"; + version = "1.0.0"; + src = fetchFromGitHub { + # path to the upstream repository + }; + + dontBuild = true; + installPhase = '' + mkdir -p $out/share/zsh/site-functions + cp {themes,plugins} $out/share/zsh + cp completions $out/share/zsh/site-functions + ''; +} + + +
+
diff --git a/pkgs/shells/zsh/lambda-mod-zsh-theme/default.nix b/pkgs/shells/zsh/lambda-mod-zsh-theme/default.nix index 6dea51a487e9..c4d63bd27710 100644 --- a/pkgs/shells/zsh/lambda-mod-zsh-theme/default.nix +++ b/pkgs/shells/zsh/lambda-mod-zsh-theme/default.nix @@ -1,4 +1,4 @@ -{ stdenv, fetchFromGitHub }: +{ stdenv, fetchFromGitHub, zsh }: stdenv.mkDerivation { name = "lambda-mod-zsh-theme-unstable-2017-10-08"; @@ -10,9 +10,13 @@ stdenv.mkDerivation { rev = "61c373c8aa5556d51522290b82ad44e7166bced1"; }; + buildInputs = [ zsh ]; + installPhase = '' - mkdir -p $out/share/themes - cp lambda-mod.zsh-theme $out/share/themes + chmod +x lambda-mod.zsh-theme # only executable scripts are found by `patchShebangs` + patchShebangs . + + install -Dm0644 lambda-mod.zsh-theme $out/share/zsh/themes/lambda-mod.zsh-theme ''; meta = with stdenv.lib; { diff --git a/pkgs/shells/zsh/nix-zsh-completions/default.nix b/pkgs/shells/zsh/nix-zsh-completions/default.nix index 3c4c3fabfd10..4405902ec3e0 100644 --- a/pkgs/shells/zsh/nix-zsh-completions/default.nix +++ b/pkgs/shells/zsh/nix-zsh-completions/default.nix @@ -15,15 +15,16 @@ stdenv.mkDerivation rec { }; installPhase = '' - mkdir -p $out/share/zsh/site-functions + mkdir -p $out/share/zsh/{site-functions,plugins/nix} cp _* $out/share/zsh/site-functions + cp *.zsh $out/share/zsh/plugins/nix ''; - meta = { + meta = with stdenv.lib; { homepage = https://github.com/spwhitt/nix-zsh-completions; description = "ZSH completions for Nix, NixOS, and NixOps"; - license = stdenv.lib.licenses.bsd3; - platforms = stdenv.lib.platforms.all; - maintainers = [ stdenv.lib.maintainers.spwhitt stdenv.lib.maintainers.olejorgenb stdenv.lib.maintainers.hedning ]; + license = licenses.bsd3; + platforms = platforms.all; + maintainers = with maintainers; [ spwhitt olejorgenb hedning ma27 ]; }; }