Jump to content

Zsh: Difference between revisions

From NixOS Wiki
imported>Flexagoon
No edit summary
Pigs (talk | contribs)
Reorganize page layout, add configuration options for system wide zsh usage, and make it clear when the article is talking about system configuration vs home manager
 
(35 intermediate revisions by 32 users not shown)
Line 1: Line 1:
[https://www.zsh.org/ Zsh] is a powerful [[Command Shell|shell]] that operates as both an interactive shell and as a scripting language interpreter. While being compatible with the POSIX sh (not by default, only if issuing {{ic|emulate sh}}), it offers advantages such as improved [http://zsh.sourceforge.net/Guide/zshguide06.html tab completion] and [http://zsh.sourceforge.net/Doc/Release/Expansion.html globbing].
[https://www.zsh.org/ Zsh] is a powerful Unix [https://wiki.nixos.org/wiki/Command_Shell shell] that functions both as an interactive shell and a scripting language interpreter. It extends the Bourne Shell (sh) with features from bash, ksh, and tcsh, offering [http://zsh.sourceforge.net/Guide/zshguide06.html advanced tab completion], improved [http://zsh.sourceforge.net/Doc/Release/Expansion.html globbing], and extensive customization options. Though not POSIX sh-compatible by default, it can be configured to be so with <code>emulate sh</code>.
 
Key features include highly customizable prompts, enhanced command history, spelling correction, and robust job control. The Oh My Zsh framework simplifies managing plugins and themes. Zsh is cross-platform, available on Unix-like systems including Linux and macOS, and is popular among developers and system administrators for its advanced features and user-friendly enhancements.


The [http://zsh.sourceforge.net/FAQ/zshfaq01.html#l4 Zsh FAQ] offers more reasons to use Zsh.
The [http://zsh.sourceforge.net/FAQ/zshfaq01.html#l4 Zsh FAQ] offers more reasons to use Zsh.


== Installation ==
== Installation ==
See [[Command Shell]].
 
=== NixOS system installation ===
 
To install zsh for a user on a regular nixos system:
 
{{file|/etc/nixos/configuration.nix|nix|
<nowiki>
  programs.zsh.enable = true;
  users.extraUsers.myuser = {
    ...
    shell = pkgs.zsh;
  };
</nowiki>
}}
Replace <code>myuser</code> with the appropriate username.
 
See [[Command Shell]] for more information.
 
=== Home Manager ===
 
For a user-specific installation managed by [[Home Manager]], use the following configuration:
 
{{file|home.nix|nix|
<nowiki>
  home-manager.users.myuser = {
    programs.zsh.enable = true;
  };
</nowiki>
}}
 
Replace <code>myuser</code> with the appropriate username.
 
You can enable the zsh shell and manage zsh configuration and plugins with Home Manager, but to enable vendor zsh completions provided by Nixpkgs you will also want to enable the zsh shell:
 
{{file|/etc/nixos/configuration.nix|nix|
<nowiki>
  programs.zsh.enable = true;
</nowiki>
}}


== Configuration ==
== Configuration ==
Zsh can be configured with [[Home Manager]].


Full list of home-manager options for zsh can be found [https://rycee.gitlab.io/home-manager/options.html#opt-wayland.windowManager.sway.enable here.]
=== NixOS system configuration ===
 
The following example demonstrates how to configure zsh system-wide through the NixOS configuration:
 
{{file|/etc/nixos/configuration.nix|nix|
<nowiki>
  programs.zsh = {
    enable = true;
    enableCompletion = true;
    autosuggestions.enable = true;
    syntaxHighlighting.enable = true;
 
    shellAliases = {
      ll = "ls -l";
      edit = "sudo -e";
      update = "sudo nixos-rebuild switch";
    };
 
    histSize = 10000;
    histFile = "$HOME/.zsh_history";
    setOptions = [
      "HIST_IGNORE_ALL_DUPS"
    ];
  };
</nowiki>
}}


=== Example Configuration ===
For a full list of zsh module options, refer to {{nixos:option|programs.zsh}}.
{{file|~/.config/nixpkgs/home.nix|nix|<nowiki>
 
programs.zsh = {
==== Plugins ====  
  enable = true;
 
  shellAliases = {
The most straightforward way to manage Zsh plugins on NixOS is by enabling the <code>ohMyZsh</code> plugin manager, as demonstrated in the example below:
    ll = "ls -l";
 
    update = "sudo nixos-rebuild switch";
{{file|/etc/nixos/configuration.nix|nix|
<nowiki>
  programs.zsh = {
    enable = true;
    ohMyZsh = {
      enable = true;
      plugins = [
        "git"
        "z"
      ];
      theme = "robbyrussell";
    };
   };
   };
   history = {
</nowiki>
     size = 10000;
}}
     path = "${config.xdg.dataHome}/zsh/history";
 
Alternatively, individual Zsh plugins are available as {{nixos:package|zsh-*}} packages within Nixpkgs. When using this method, plugins must be manually sourced within the Zsh configuration file.
 
=== Home Manager ===
 
The configuration below is using [[Home Manager]], but a more limited version of it can be achieved if system-wide.
 
{{file|home.nix|nix|
<nowiki>
   programs.zsh = {
    enable = true;
    enableCompletion = true;
    autosuggestion.enable = true;
    syntaxHighlighting.enable = true;
 
    shellAliases = {
      ll = "ls -l";
      edit = "sudo -e";
      update = "sudo nixos-rebuild switch";
     };
 
    history.size = 10000;
     history.ignoreAllDups = true;
    history.path = "$HOME/.zsh_history";
    history.ignorePatterns = ["rm *" "pkill *" "cp *"];
   };
   };
};
</nowiki>
</nowiki>}}
}}
 
The home manager options are defined in the following [https://nix-community.github.io/home-manager/options.xhtml#opt-programs.zsh.enable Home Manager Options Manual] or can be looked up at [https://home-manager-options.extranix.com/?query=zsh&release=master Home Manager Option Search].
 
The system-wide options are listed on [https://search.nixos.org/options?query=programs.zsh programs.zsh.*].
 
==== Plugins ====


=== Plugin Management ===
Home manager has four ways of managing plugins: '''[http://zplug.github.io/ Zplug]''', '''[https://ohmyz.sh/ Oh-My-Zsh], [https://getantidote.github.io/ Antidote]''' and '''manually'''.
Home manager has three ways of managing plugins: Zplug, Oh-My-Zsh and manual.


==== Zplug ====
{{file|home.nix|nix|
{{file|~/.config/nixpkgs/home.nix|nix|<nowiki>
<nowiki>
programs.zsh = {
programs.zsh = {
   ... # Your zsh config
   enable = true;
 
# With Zplug:
   zplug = {
   zplug = {
     enable = true;
     enable = true;
     plugins = [
     plugins = [
       { name = "zsh-users/zsh-autosuggestions"; } # Simple plugin installation
       {name = "zsh-users/zsh-autosuggestions";} # Simple plugin installation
       { name = "romkatv/powerlevel10k"; tags = [ as:theme depth:1 ]; } # Installations with additional options. For the list of options, please refer to Zplug README.
       {
        name = "romkatv/powerlevel10k";
        tags = [ "as:theme" "depth:1" ];
      } # Installations with additional options. For the list of options, please refer to Zplug README.
     ];
     ];
   };
   };
};
 
</nowiki>}}
# With Oh-My-Zsh:
==== Oh-My-Zsh ====
{{file|~/.config/nixpkgs/home.nix|nix|<nowiki>
programs.zsh = {
  ... # Your zsh config
   oh-my-zsh = {
   oh-my-zsh = {
     enable = true;
     enable = true;
     plugins = [ "git" "thefuck" ];
     plugins = [
     theme = "robbyrussel";
      "git"         # also requires `programs.git.enable = true;`
      "thefuck"     # also requires `programs.thefuck.enable = true;`
    ];
     theme = "robbyrussell";
   };
   };
};
 
</nowiki>}}
# With Antidote:
==== Manual ====
  antidote = {
{{file|~/.config/nixpkgs/home.nix|nix|<nowiki>
    enable = true;
programs.zsh = {
    plugins = [''
  ... # Your zsh config
      zsh-users/zsh-autosuggestions
      ohmyzsh/ohmyzsh path:lib/git.zsh
    '']; # explanation of "path:..." and other options explained in Antidote README.
 
# Manual
   plugins = [
   plugins = [
     {
     {
      # will source zsh-autosuggestions.plugin.zsh
       name = "zsh-autocomplete";
       name = "zsh-autosuggestions";
       src = pkgs.fetchFromGitHub {
       src = pkgs.fetchFromGitHub {
         owner = "zsh-users";
         owner = "marlonrichert";
         repo = "zsh-autosuggestions";
         repo = "zsh-autocomplete";
         rev = "v0.4.0";
         rev = "23.07.13";
         sha256 = "0z6i9wjjklb4lvr7zjhbphibsyx51psv50gm07mbb0kj9058j6kc";
         sha256 = "sha256-/6V6IHwB5p0GT1u5SAiUa20LjFDSrMo731jFBq/bnpw=";
       };
       };
     }
     }
     {
     {
       name = "enhancd";
       name = "powerlevel10k";
       file = "init.sh";
      src = pkgs.zsh-powerlevel10k;
      file = "share/zsh-powerlevel10k/powerlevel10k.zsh-theme";
    }
    {
      name = "powerlevel10k-config";
      src = ./p10k-config;
       file = "p10k.zsh";
    }
    {
      name = "zsh-syntax-highlighting";
       src = pkgs.fetchFromGitHub {
       src = pkgs.fetchFromGitHub {
         owner = "b4b4r07";
         owner = "zsh-users";
         repo = "enhancd";
         repo = "zsh-syntax-highlighting";
         rev = "v2.2.1";
         rev = "0.8.0";
         sha256 = "0iqa9j09fwm6nj5rpip87x3hnvbbz9w9ajgm6wkrd5fls8fn8i5g";
         sha256 = "sha256-iJdWopZwHpSyYl5/FQXEW7gl/SrKaYDEtTH9cGP7iPo=";
       };
       };
     }
     }
   ];
   ];
};
};
</nowiki>}}
</nowiki>
}}
 
An example of less verbatim approach to sourcing packaged plugins can be [https://discourse.nixos.org/t/zsh-users-how-do-you-manage-plugins/9199/8 found here] and [https://discourse.nixos.org/t/zsh-users-how-do-you-manage-plugins/9199/10 here].


== Troubleshooting ==
== Troubleshooting ==
=== Zsh-autocomplete not working ===
 
==== Zsh-autocomplete not working ====
You may have some issues with the {{ic|marlonrichert/zsh-autocomplete}} plugin on NixOS. That's because the default NixOS configuration overrides keybinds for up and down arrow keys. To fix this issue, you need to add this somewhere in your .zshrc (either manually if your .zshrc is not managed by Nix, or with {{ic|packages.zsh.initExtra}})
You may have some issues with the {{ic|marlonrichert/zsh-autocomplete}} plugin on NixOS. That's because the default NixOS configuration overrides keybinds for up and down arrow keys. To fix this issue, you need to add this somewhere in your .zshrc (either manually if your .zshrc is not managed by Nix, or with {{ic|packages.zsh.initExtra}})
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 89: Line 214:
</syntaxhighlight>
</syntaxhighlight>


== See also ==
==== SHA Mismatch during manual plugin installation ====
* [[Command Shell]]
If manual plugin installation fails with SHA mismatch, generating a valid hash as part of the error message can be achieved by temporarily switching to:
<syntaxhighlight lang="nix">
sha256 = lib.fakeSha256;
</syntaxhighlight>
 
This will print a valid SHA to the console and then can be used as final value for the sha256 field.
Redoing this is mandatory if one wants to update to a newer commit of the targeted plugin repository.
 
==== GDM does not show user when zsh is the default shell ====
GDM only shows users that have their default shell set to a shell listed in /etc/shells. Setting the default shell using the following does not update /etc/shells.
<syntaxhighlight lang="nix">
users.defaultUserShell = pkgs.zsh;
</syntaxhighlight>
To add the zsh package to /etc/shells you must update environment.shells.
<syntaxhighlight lang="nix">
environment.shells = with pkgs; [ zsh ];
</syntaxhighlight>
 
==== Hide configuration for new users ====
Meaning this message:<syntaxhighlight lang="zsh">
This is the Z Shell configuration function for new users,
zsh-newuser-install.
You are seeing this message because you have no zsh startup files
(the files .zshenv, .zprofile, .zshrc, .zlogin in the directory
~).  This function can help you with a few settings that should
make your use of the shell easier.
 
You can:
 
(q)  Quit and do nothing.  The function will be run again next time.
 
(0)  Exit, creating the file ~/.zshrc containing just a comment.
    That will prevent this function being run again.
 
(1)  Continue to the main menu.
 
--- Type one of the keys in parentheses ---
</syntaxhighlight>You can hide this message by adding following line to the system configuration:<syntaxhighlight lang="nixos">
# Prevent the new user dialog in zsh
system.userActivationScripts.zshrc = "touch .zshrc";
</syntaxhighlight>
 
== References ==
 
# https://www.zsh.org/
# http://zsh.sourceforge.net/Guide/zshguide06.html
# http://zsh.sourceforge.net/Doc/Release/Expansion.html
# http://zsh.sourceforge.net/FAQ/zshfaq01.html#l4
# https://nix-community.github.io/home-manager/options.xhtml#opt-programs.zsh.enable
# https://search.nixos.org/options?query=programs.zsh
 
[[Category:Shell]]
[[Category:NixOS Manual]]

Latest revision as of 00:48, 14 May 2025

Zsh is a powerful Unix shell that functions both as an interactive shell and a scripting language interpreter. It extends the Bourne Shell (sh) with features from bash, ksh, and tcsh, offering advanced tab completion, improved globbing, and extensive customization options. Though not POSIX sh-compatible by default, it can be configured to be so with emulate sh.

Key features include highly customizable prompts, enhanced command history, spelling correction, and robust job control. The Oh My Zsh framework simplifies managing plugins and themes. Zsh is cross-platform, available on Unix-like systems including Linux and macOS, and is popular among developers and system administrators for its advanced features and user-friendly enhancements.

The Zsh FAQ offers more reasons to use Zsh.

Installation

NixOS system installation

To install zsh for a user on a regular nixos system:

❄︎ /etc/nixos/configuration.nix
  programs.zsh.enable = true;
  users.extraUsers.myuser = {
    ...
    shell = pkgs.zsh;
  };

Replace myuser with the appropriate username.

See Command Shell for more information.

Home Manager

For a user-specific installation managed by Home Manager, use the following configuration:

❄︎ home.nix
  home-manager.users.myuser = {
    programs.zsh.enable = true;
  };

Replace myuser with the appropriate username.

You can enable the zsh shell and manage zsh configuration and plugins with Home Manager, but to enable vendor zsh completions provided by Nixpkgs you will also want to enable the zsh shell:

❄︎ /etc/nixos/configuration.nix
  programs.zsh.enable = true;

Configuration

NixOS system configuration

The following example demonstrates how to configure zsh system-wide through the NixOS configuration:

❄︎ /etc/nixos/configuration.nix
  programs.zsh = {
    enable = true;
    enableCompletion = true;
    autosuggestions.enable = true;
    syntaxHighlighting.enable = true;

    shellAliases = {
      ll = "ls -l";
      edit = "sudo -e";
      update = "sudo nixos-rebuild switch";
    };

    histSize = 10000;
    histFile = "$HOME/.zsh_history";
    setOptions = [
      "HIST_IGNORE_ALL_DUPS"
    ];
  };

For a full list of zsh module options, refer to programs.zsh.

Plugins

The most straightforward way to manage Zsh plugins on NixOS is by enabling the ohMyZsh plugin manager, as demonstrated in the example below:

❄︎ /etc/nixos/configuration.nix
  programs.zsh = {
    enable = true;
    ohMyZsh = {
      enable = true;
      plugins = [
        "git"
        "z"
      ];
      theme = "robbyrussell";
    };
  };

Alternatively, individual Zsh plugins are available as zsh-* packages within Nixpkgs. When using this method, plugins must be manually sourced within the Zsh configuration file.

Home Manager

The configuration below is using Home Manager, but a more limited version of it can be achieved if system-wide.

❄︎ home.nix
  programs.zsh = {
    enable = true;
    enableCompletion = true;
    autosuggestion.enable = true;
    syntaxHighlighting.enable = true;

    shellAliases = {
      ll = "ls -l";
      edit = "sudo -e";
      update = "sudo nixos-rebuild switch";
    };

    history.size = 10000;
    history.ignoreAllDups = true;
    history.path = "$HOME/.zsh_history";
    history.ignorePatterns = ["rm *" "pkill *" "cp *"];
  };

The home manager options are defined in the following Home Manager Options Manual or can be looked up at Home Manager Option Search.

The system-wide options are listed on programs.zsh.*.

Plugins

Home manager has four ways of managing plugins: Zplug, Oh-My-Zsh, Antidote and manually.

❄︎ home.nix
programs.zsh = {
  enable = true;

# With Zplug:
  zplug = {
    enable = true;
    plugins = [
      {name = "zsh-users/zsh-autosuggestions";} # Simple plugin installation
      {
        name = "romkatv/powerlevel10k";
        tags = [ "as:theme" "depth:1" ];
      } # Installations with additional options. For the list of options, please refer to Zplug README.
    ];
  };

# With Oh-My-Zsh:
  oh-my-zsh = {
    enable = true;
    plugins = [
      "git"         # also requires `programs.git.enable = true;`
      "thefuck"     # also requires `programs.thefuck.enable = true;` 
    ];
    theme = "robbyrussell";
  };

# With Antidote:
  antidote = {
    enable = true;
    plugins = [''
      zsh-users/zsh-autosuggestions
      ohmyzsh/ohmyzsh path:lib/git.zsh
    '']; # explanation of "path:..." and other options explained in Antidote README.

# Manual
  plugins = [
    {
      name = "zsh-autocomplete";
      src = pkgs.fetchFromGitHub {
        owner = "marlonrichert";
        repo = "zsh-autocomplete";
        rev = "23.07.13";
        sha256 = "sha256-/6V6IHwB5p0GT1u5SAiUa20LjFDSrMo731jFBq/bnpw=";
      };
    }
    {
      name = "powerlevel10k";
      src = pkgs.zsh-powerlevel10k;
      file = "share/zsh-powerlevel10k/powerlevel10k.zsh-theme";
    }
    {
      name = "powerlevel10k-config";
      src = ./p10k-config;
      file = "p10k.zsh";
    }
    {
      name = "zsh-syntax-highlighting";
      src = pkgs.fetchFromGitHub {
        owner = "zsh-users";
        repo = "zsh-syntax-highlighting";
        rev = "0.8.0";
        sha256 = "sha256-iJdWopZwHpSyYl5/FQXEW7gl/SrKaYDEtTH9cGP7iPo=";
      };
    }
  ];
};

An example of less verbatim approach to sourcing packaged plugins can be found here and here.

Troubleshooting

Zsh-autocomplete not working

You may have some issues with the marlonrichert/zsh-autocomplete plugin on NixOS. That's because the default NixOS configuration overrides keybinds for up and down arrow keys. To fix this issue, you need to add this somewhere in your .zshrc (either manually if your .zshrc is not managed by Nix, or with packages.zsh.initExtra)

bindkey "''${key[Up]}" up-line-or-search

SHA Mismatch during manual plugin installation

If manual plugin installation fails with SHA mismatch, generating a valid hash as part of the error message can be achieved by temporarily switching to:

sha256 = lib.fakeSha256;

This will print a valid SHA to the console and then can be used as final value for the sha256 field. Redoing this is mandatory if one wants to update to a newer commit of the targeted plugin repository.

GDM does not show user when zsh is the default shell

GDM only shows users that have their default shell set to a shell listed in /etc/shells. Setting the default shell using the following does not update /etc/shells.

users.defaultUserShell = pkgs.zsh;

To add the zsh package to /etc/shells you must update environment.shells.

environment.shells = with pkgs; [ zsh ];

Hide configuration for new users

Meaning this message:

This is the Z Shell configuration function for new users,
zsh-newuser-install.
You are seeing this message because you have no zsh startup files
(the files .zshenv, .zprofile, .zshrc, .zlogin in the directory
~).  This function can help you with a few settings that should
make your use of the shell easier.

You can:

(q)  Quit and do nothing.  The function will be run again next time.

(0)  Exit, creating the file ~/.zshrc containing just a comment.
     That will prevent this function being run again.

(1)  Continue to the main menu.

--- Type one of the keys in parentheses ---

You can hide this message by adding following line to the system configuration:

# Prevent the new user dialog in zsh
system.userActivationScripts.zshrc = "touch .zshrc";

References

  1. https://www.zsh.org/
  2. http://zsh.sourceforge.net/Guide/zshguide06.html
  3. http://zsh.sourceforge.net/Doc/Release/Expansion.html
  4. http://zsh.sourceforge.net/FAQ/zshfaq01.html#l4
  5. https://nix-community.github.io/home-manager/options.xhtml#opt-programs.zsh.enable
  6. https://search.nixos.org/options?query=programs.zsh