nixpkgs/nixos/modules/programs/zsh/oh-my-zsh.md
Janne Heß bc77c7a973 treewide: Mark Nix blocks in markdown as Nix
This should help us with highlighting and future formatting.
2024-03-28 09:28:12 +01:00

3.5 KiB

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.zsh.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.zsh.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.zsh.ohMyZsh.customPkgs = [
    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.zsh.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
  '';
}