diff options
author | Alyssa Ross <hi@alyssa.is> | 2022-05-31 09:59:33 +0000 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2022-05-31 09:59:57 +0000 |
commit | 9ff36293d1e428cd7bf03e8d4b03611b6d361c28 (patch) | |
tree | 1ab51a42b868c55b83f6ccdb80371b9888739dd9 /nixos/modules/programs/zsh | |
parent | 1c4fcd0d4b0541e674ee56ace1053e23e562cc80 (diff) | |
parent | ddc3c396a51918043bb0faa6f676abd9562be62c (diff) | |
download | nixpkgs-9ff36293d1e428cd7bf03e8d4b03611b6d361c28.tar nixpkgs-9ff36293d1e428cd7bf03e8d4b03611b6d361c28.tar.gz nixpkgs-9ff36293d1e428cd7bf03e8d4b03611b6d361c28.tar.bz2 nixpkgs-9ff36293d1e428cd7bf03e8d4b03611b6d361c28.tar.lz nixpkgs-9ff36293d1e428cd7bf03e8d4b03611b6d361c28.tar.xz nixpkgs-9ff36293d1e428cd7bf03e8d4b03611b6d361c28.tar.zst nixpkgs-9ff36293d1e428cd7bf03e8d4b03611b6d361c28.zip |
Last good Nixpkgs for Weston+nouveau? archive
I came this commit hash to terwiz[m] on IRC, who is trying to figure out what the last version of Spectrum that worked on their NUC with Nvidia graphics is.
Diffstat (limited to 'nixos/modules/programs/zsh')
-rw-r--r-- | nixos/modules/programs/zsh/oh-my-zsh.nix | 146 | ||||
-rw-r--r-- | nixos/modules/programs/zsh/oh-my-zsh.xml | 155 | ||||
-rw-r--r-- | nixos/modules/programs/zsh/zinputrc | 42 | ||||
-rw-r--r-- | nixos/modules/programs/zsh/zsh-autoenv.nix | 28 | ||||
-rw-r--r-- | nixos/modules/programs/zsh/zsh-autosuggestions.nix | 73 | ||||
-rw-r--r-- | nixos/modules/programs/zsh/zsh-syntax-highlighting.nix | 107 | ||||
-rw-r--r-- | nixos/modules/programs/zsh/zsh.nix | 303 |
7 files changed, 854 insertions, 0 deletions
diff --git a/nixos/modules/programs/zsh/oh-my-zsh.nix b/nixos/modules/programs/zsh/oh-my-zsh.nix new file mode 100644 index 00000000000..9d7622bd328 --- /dev/null +++ b/nixos/modules/programs/zsh/oh-my-zsh.nix @@ -0,0 +1,146 @@ +{ config, lib, pkgs, ... }: + +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 + { + imports = [ + (mkRenamedOptionModule [ "programs" "zsh" "oh-my-zsh" "enable" ] [ "programs" "zsh" "ohMyZsh" "enable" ]) + (mkRenamedOptionModule [ "programs" "zsh" "oh-my-zsh" "theme" ] [ "programs" "zsh" "ohMyZsh" "theme" ]) + (mkRenamedOptionModule [ "programs" "zsh" "oh-my-zsh" "custom" ] [ "programs" "zsh" "ohMyZsh" "custom" ]) + (mkRenamedOptionModule [ "programs" "zsh" "oh-my-zsh" "plugins" ] [ "programs" "zsh" "ohMyZsh" "plugins" ]) + ]; + + options = { + programs.zsh.ohMyZsh = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable oh-my-zsh. + ''; + }; + + package = mkOption { + default = pkgs.oh-my-zsh; + defaultText = literalExpression "pkgs.oh-my-zsh"; + description = '' + Package to install for `oh-my-zsh` usage. + ''; + + type = types.package; + }; + + plugins = mkOption { + default = []; + type = types.listOf(types.str); + description = '' + List of oh-my-zsh plugins + ''; + }; + + custom = mkOption { + 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`. + ''; + }; + + theme = mkOption { + default = ""; + type = types.str; + description = '' + Name of the theme to be used by oh-my-zsh. + ''; + }; + + cacheDir = mkOption { + default = "$HOME/.cache/oh-my-zsh"; + type = types.str; + description = '' + Cache directory to be used by `oh-my-zsh`. + Without this option it would default to the read-only nix store. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + + # Prevent zsh from overwriting oh-my-zsh's prompt + programs.zsh.promptInit = mkDefault ""; + + environment.systemPackages = [ cfg.package ]; + + programs.zsh.interactiveShellInit = '' + # oh-my-zsh configuration generated by NixOS + export ZSH=${cfg.package}/share/oh-my-zsh + + ${optionalString (length(cfg.plugins) > 0) + "plugins=(${concatStringsSep " " cfg.plugins})" + } + + ${optionalString (custom != null) + "ZSH_CUSTOM=\"${custom}\"" + } + + ${optionalString (stringLength(cfg.theme) > 0) + "ZSH_THEME=\"${cfg.theme}\"" + } + + ${optionalString (cfg.cacheDir != null) '' + if [[ ! -d "${cfg.cacheDir}" ]]; then + mkdir -p "${cfg.cacheDir}" + fi + ZSH_CACHE_DIR=${cfg.cacheDir} + ''} + + 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 00000000000..14a7228ad9b --- /dev/null +++ b/nixos/modules/programs/zsh/oh-my-zsh.xml @@ -0,0 +1,155 @@ +<chapter xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="module-programs-zsh-ohmyzsh"> + <title>Oh my ZSH</title> + <para> + <literal><link xlink:href="https://ohmyz.sh/">oh-my-zsh</link></literal> is a + framework to manage your <link xlink:href="https://www.zsh.org/">ZSH</link> + configuration including completion scripts for several CLI tools or custom + prompt themes. + </para> + <section xml:id="module-programs-oh-my-zsh-usage"> + <title>Basic usage</title> + + <para> + The module uses the <literal>oh-my-zsh</literal> package with all available + features. The initial setup using Nix expressions is fairly similar to the + configuration format of <literal>oh-my-zsh</literal>. +<programlisting> +{ + programs.zsh.ohMyZsh = { + enable = true; + plugins = [ "git" "python" "man" ]; + theme = "agnoster"; + }; +} +</programlisting> + For a detailed explanation of these arguments please refer to the + <link xlink:href="https://github.com/robbyrussell/oh-my-zsh/wiki"><literal>oh-my-zsh</literal> + docs</link>. + </para> + + <para> + The expression generates the needed configuration and writes it into your + <literal>/etc/zshrc</literal>. + </para> + </section> + <section xml:id="module-programs-oh-my-zsh-additions"> + <title>Custom additions</title> + + <para> + Sometimes third-party or custom scripts such as a modified theme may be + needed. <literal>oh-my-zsh</literal> provides the + <link xlink:href="https://github.com/robbyrussell/oh-my-zsh/wiki/Customization#overriding-internals"><literal>ZSH_CUSTOM</literal></link> + environment variable for this which points to a directory with additional + scripts. + </para> + + <para> + The module can do this as well: +<programlisting> +{ + programs.zsh.ohMyZsh.custom = "~/path/to/custom/scripts"; +} +</programlisting> + </para> + </section> + <section xml:id="module-programs-oh-my-zsh-environments"> + <title>Custom environments</title> + + <para> + There are several extensions for <literal>oh-my-zsh</literal> packaged in + <literal>nixpkgs</literal>. One of them is + <link xlink:href="https://github.com/spwhitt/nix-zsh-completions">nix-zsh-completions</link> + which bundles completion scripts and a plugin for + <literal>oh-my-zsh</literal>. + </para> + + <para> + Rather than using a single mutable path for <literal>ZSH_CUSTOM</literal>, + it's also possible to generate this path from a list of Nix packages: +<programlisting> +{ pkgs, ... }: +{ + programs.zsh.ohMyZsh.customPkgs = [ + pkgs.nix-zsh-completions + # and even more... + ]; +} +</programlisting> + Internally a single store path will be created using + <literal>buildEnv</literal>. Please refer to the docs of + <link xlink:href="https://nixos.org/nixpkgs/manual/#sec-building-environment"><literal>buildEnv</literal></link> + for further reference. + </para> + + <para> + <emphasis>Please keep in mind that this is not compatible with + <literal>programs.zsh.ohMyZsh.custom</literal> as it requires an immutable + store path while <literal>custom</literal> shall remain mutable! An + evaluation failure will be thrown if both <literal>custom</literal> and + <literal>customPkgs</literal> are set.</emphasis> + </para> + </section> + <section xml:id="module-programs-oh-my-zsh-packaging-customizations"> + <title>Package your own customizations</title> + + <para> + If third-party customizations (e.g. new themes) are supposed to be added to + <literal>oh-my-zsh</literal> there are several pitfalls to keep in mind: + </para> + + <itemizedlist> + <listitem> + <para> + To comply with the default structure of <literal>ZSH</literal> the entire + output needs to be written to <literal>$out/share/zsh.</literal> + </para> + </listitem> + <listitem> + <para> + Completion scripts are supposed to be stored at + <literal>$out/share/zsh/site-functions</literal>. This directory is part + of the + <literal><link xlink:href="http://zsh.sourceforge.net/Doc/Release/Functions.html">fpath</link></literal> + and the package should be compatible with pure <literal>ZSH</literal> + setups. The module will automatically link the contents of + <literal>site-functions</literal> to completions directory in the proper + store path. + </para> + </listitem> + <listitem> + <para> + The <literal>plugins</literal> directory needs the structure + <literal>pluginname/pluginname.plugin.zsh</literal> as structured in the + <link xlink:href="https://github.com/robbyrussell/oh-my-zsh/tree/91b771914bc7c43dd7c7a43b586c5de2c225ceb7/plugins">upstream + repo.</link> + </para> + </listitem> + </itemizedlist> + + <para> + A derivation for <literal>oh-my-zsh</literal> may look like this: +<programlisting> +{ 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 + ''; +} +</programlisting> + </para> + </section> +</chapter> diff --git a/nixos/modules/programs/zsh/zinputrc b/nixos/modules/programs/zsh/zinputrc new file mode 100644 index 00000000000..6121f3e21f1 --- /dev/null +++ b/nixos/modules/programs/zsh/zinputrc @@ -0,0 +1,42 @@ +# Stolen from ArchWiki + +# create a zkbd compatible hash; +# to add other keys to this hash, see: man 5 terminfo +typeset -A key + +key[Home]=${terminfo[khome]} + +key[End]=${terminfo[kend]} +key[Insert]=${terminfo[kich1]} +key[Delete]=${terminfo[kdch1]} +key[Up]=${terminfo[kcuu1]} +key[Down]=${terminfo[kcud1]} +key[Left]=${terminfo[kcub1]} +key[Right]=${terminfo[kcuf1]} +key[PageUp]=${terminfo[kpp]} +key[PageDown]=${terminfo[knp]} + +# setup key accordingly +[[ -n "${key[Home]}" ]] && bindkey "${key[Home]}" beginning-of-line +[[ -n "${key[End]}" ]] && bindkey "${key[End]}" end-of-line +[[ -n "${key[Insert]}" ]] && bindkey "${key[Insert]}" overwrite-mode +[[ -n "${key[Delete]}" ]] && bindkey "${key[Delete]}" delete-char +[[ -n "${key[Up]}" ]] && bindkey "${key[Up]}" up-line-or-history +[[ -n "${key[Down]}" ]] && bindkey "${key[Down]}" down-line-or-history +[[ -n "${key[Left]}" ]] && bindkey "${key[Left]}" backward-char +[[ -n "${key[Right]}" ]] && bindkey "${key[Right]}" forward-char +[[ -n "${key[PageUp]}" ]] && bindkey "${key[PageUp]}" beginning-of-buffer-or-history +[[ -n "${key[PageDown]}" ]] && bindkey "${key[PageDown]}" end-of-buffer-or-history + +# Finally, make sure the terminal is in application mode, when zle is +# active. Only then are the values from $terminfo valid. +if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then + function zle-line-init () { + printf '%s' "${terminfo[smkx]}" + } + function zle-line-finish () { + printf '%s' "${terminfo[rmkx]}" + } + zle -N zle-line-init + zle -N zle-line-finish +fi diff --git a/nixos/modules/programs/zsh/zsh-autoenv.nix b/nixos/modules/programs/zsh/zsh-autoenv.nix new file mode 100644 index 00000000000..62f497a45dd --- /dev/null +++ b/nixos/modules/programs/zsh/zsh-autoenv.nix @@ -0,0 +1,28 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.zsh.zsh-autoenv; +in { + options = { + programs.zsh.zsh-autoenv = { + enable = mkEnableOption "zsh-autoenv"; + package = mkOption { + default = pkgs.zsh-autoenv; + defaultText = literalExpression "pkgs.zsh-autoenv"; + description = '' + Package to install for `zsh-autoenv` usage. + ''; + + type = types.package; + }; + }; + }; + + config = mkIf cfg.enable { + programs.zsh.interactiveShellInit = '' + source ${cfg.package}/share/zsh-autoenv/autoenv.zsh + ''; + }; +} diff --git a/nixos/modules/programs/zsh/zsh-autosuggestions.nix b/nixos/modules/programs/zsh/zsh-autosuggestions.nix new file mode 100644 index 00000000000..2e53e907d54 --- /dev/null +++ b/nixos/modules/programs/zsh/zsh-autosuggestions.nix @@ -0,0 +1,73 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.programs.zsh.autosuggestions; +in +{ + imports = [ + (mkRenamedOptionModule [ "programs" "zsh" "enableAutosuggestions" ] [ "programs" "zsh" "autosuggestions" "enable" ]) + ]; + + options.programs.zsh.autosuggestions = { + + enable = mkEnableOption "zsh-autosuggestions"; + + highlightStyle = mkOption { + type = types.str; + default = "fg=8"; # https://github.com/zsh-users/zsh-autosuggestions/tree/v0.4.3#suggestion-highlight-style + description = "Highlight style for suggestions ({fore,back}ground color)"; + example = "fg=cyan"; + }; + + strategy = mkOption { + type = types.listOf (types.enum [ "history" "completion" "match_prev_cmd" ]); + default = [ "history" ]; + description = '' + `ZSH_AUTOSUGGEST_STRATEGY` is an array that specifies how suggestions should be generated. + The strategies in the array are tried successively until a suggestion is found. + There are currently three built-in strategies to choose from: + + - `history`: Chooses the most recent match from history. + - `completion`: Chooses a suggestion based on what tab-completion would suggest. (requires `zpty` module) + - `match_prev_cmd`: Like `history`, but chooses the most recent match whose preceding history item matches + the most recently executed command. Note that this strategy won't work as expected with ZSH options that + don't preserve the history order such as `HIST_IGNORE_ALL_DUPS` or `HIST_EXPIRE_DUPS_FIRST`. + ''; + }; + + async = mkOption { + type = types.bool; + default = true; + description = "Whether to fetch suggestions asynchronously"; + example = false; + }; + + extraConfig = mkOption { + type = with types; attrsOf str; + default = {}; + description = "Attribute set with additional configuration values"; + example = literalExpression '' + { + "ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE" = "20"; + } + ''; + }; + + }; + + config = mkIf cfg.enable { + + programs.zsh.interactiveShellInit = '' + source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh + + export ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="${cfg.highlightStyle}" + export ZSH_AUTOSUGGEST_STRATEGY=(${concatStringsSep " " cfg.strategy}) + ${optionalString (!cfg.async) "unset ZSH_AUTOSUGGEST_USE_ASYNC"} + + ${concatStringsSep "\n" (mapAttrsToList (key: value: ''export ${key}="${value}"'') cfg.extraConfig)} + ''; + + }; +} diff --git a/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix b/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix new file mode 100644 index 00000000000..1eb53ccae52 --- /dev/null +++ b/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix @@ -0,0 +1,107 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.zsh.syntaxHighlighting; +in +{ + imports = [ + (mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ]) + (mkRenamedOptionModule [ "programs" "zsh" "syntax-highlighting" "enable" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ]) + (mkRenamedOptionModule [ "programs" "zsh" "syntax-highlighting" "highlighters" ] [ "programs" "zsh" "syntaxHighlighting" "highlighters" ]) + (mkRenamedOptionModule [ "programs" "zsh" "syntax-highlighting" "patterns" ] [ "programs" "zsh" "syntaxHighlighting" "patterns" ]) + ]; + + options = { + programs.zsh.syntaxHighlighting = { + enable = mkEnableOption "zsh-syntax-highlighting"; + + highlighters = mkOption { + default = [ "main" ]; + + # https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters.md + type = types.listOf(types.enum([ + "main" + "brackets" + "pattern" + "cursor" + "root" + "line" + ])); + + description = '' + Specifies the highlighters to be used by zsh-syntax-highlighting. + + The following defined options can be found here: + https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters.md + ''; + }; + + patterns = mkOption { + default = {}; + type = types.attrsOf types.str; + + example = literalExpression '' + { + "rm -rf *" = "fg=white,bold,bg=red"; + } + ''; + + description = '' + Specifies custom patterns to be highlighted by zsh-syntax-highlighting. + + Please refer to the docs for more information about the usage: + https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters/pattern.md + ''; + }; + styles = mkOption { + default = {}; + type = types.attrsOf types.str; + + example = literalExpression '' + { + "alias" = "fg=magenta,bold"; + } + ''; + + description = '' + Specifies custom styles to be highlighted by zsh-syntax-highlighting. + + Please refer to the docs for more information about the usage: + https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters/main.md + ''; + }; + }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = with pkgs; [ zsh-syntax-highlighting ]; + + assertions = [ + { + assertion = length(attrNames cfg.patterns) > 0 -> elem "pattern" cfg.highlighters; + message = '' + When highlighting patterns, "pattern" needs to be included in the list of highlighters. + ''; + } + ]; + + programs.zsh.interactiveShellInit = with pkgs; + lib.mkAfter (lib.concatStringsSep "\n" ([ + "source ${zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" + ] ++ optional (length(cfg.highlighters) > 0) + "ZSH_HIGHLIGHT_HIGHLIGHTERS=(${concatStringsSep " " cfg.highlighters})" + ++ optionals (length(attrNames cfg.patterns) > 0) + (mapAttrsToList ( + pattern: design: + "ZSH_HIGHLIGHT_PATTERNS+=('${pattern}' '${design}')" + ) cfg.patterns) + ++ optionals (length(attrNames cfg.styles) > 0) + (mapAttrsToList ( + styles: design: + "ZSH_HIGHLIGHT_STYLES[${styles}]='${design}'" + ) cfg.styles) + )); + }; +} diff --git a/nixos/modules/programs/zsh/zsh.nix b/nixos/modules/programs/zsh/zsh.nix new file mode 100644 index 00000000000..5fe98b6801b --- /dev/null +++ b/nixos/modules/programs/zsh/zsh.nix @@ -0,0 +1,303 @@ +# This module defines global configuration for the zshell. + +{ config, lib, options, pkgs, ... }: + +with lib; + +let + + cfge = config.environment; + + cfg = config.programs.zsh; + opt = options.programs.zsh; + + zshAliases = concatStringsSep "\n" ( + mapAttrsFlatten (k: v: "alias ${k}=${escapeShellArg v}") + (filterAttrs (k: v: v != null) cfg.shellAliases) + ); + + zshStartupNotes = '' + # Note that generated /etc/zprofile and /etc/zshrc files do a lot of + # non-standard setup to make zsh usable with no configuration by default. + # + # Which means that unless you explicitly meticulously override everything + # generated, interactions between your ~/.zshrc and these files are likely + # to be rather surprising. + # + # Note however, that you can disable loading of the generated /etc/zprofile + # and /etc/zshrc (you can't disable loading of /etc/zshenv, but it is + # designed to not set anything surprising) by setting `no_global_rcs` option + # in ~/.zshenv: + # + # echo setopt no_global_rcs >> ~/.zshenv + # + # See "STARTUP/SHUTDOWN FILES" section of zsh(1) for more info. + ''; + +in + +{ + + options = { + + programs.zsh = { + + enable = mkOption { + default = false; + description = '' + Whether to configure zsh as an interactive shell. To enable zsh for + a particular user, use the <option>users.users.<name?>.shell</option> + option for that user. To enable zsh system-wide use the + <option>users.defaultUserShell</option> option. + ''; + type = types.bool; + }; + + shellAliases = mkOption { + default = { }; + description = '' + Set of aliases for zsh shell, which overrides <option>environment.shellAliases</option>. + See <option>environment.shellAliases</option> for an option format description. + ''; + type = with types; attrsOf (nullOr (either str path)); + }; + + shellInit = mkOption { + default = ""; + description = '' + Shell script code called during zsh shell initialisation. + ''; + type = types.lines; + }; + + loginShellInit = mkOption { + default = ""; + description = '' + Shell script code called during zsh login shell initialisation. + ''; + type = types.lines; + }; + + interactiveShellInit = mkOption { + default = ""; + description = '' + Shell script code called during interactive zsh shell initialisation. + ''; + type = types.lines; + }; + + promptInit = mkOption { + default = '' + # Note that to manually override this in ~/.zshrc you should run `prompt off` + # before setting your PS1 and etc. Otherwise this will likely to interact with + # your ~/.zshrc configuration in unexpected ways as the default prompt sets + # a lot of different prompt variables. + autoload -U promptinit && promptinit && prompt suse && setopt prompt_sp + ''; + description = '' + Shell script code used to initialise the zsh prompt. + ''; + type = types.lines; + }; + + histSize = mkOption { + default = 2000; + description = '' + Change history size. + ''; + type = types.int; + }; + + histFile = mkOption { + default = "$HOME/.zsh_history"; + description = '' + Change history file. + ''; + type = types.str; + }; + + setOptions = mkOption { + type = types.listOf types.str; + default = [ + "HIST_IGNORE_DUPS" + "SHARE_HISTORY" + "HIST_FCNTL_LOCK" + ]; + example = [ "EXTENDED_HISTORY" "RM_STAR_WAIT" ]; + description = '' + Configure zsh options. See + <citerefentry><refentrytitle>zshoptions</refentrytitle><manvolnum>1</manvolnum></citerefentry>. + ''; + }; + + enableCompletion = mkOption { + default = true; + description = '' + Enable zsh completion for all interactive zsh shells. + ''; + type = types.bool; + }; + + enableBashCompletion = mkOption { + default = false; + description = '' + Enable compatibility with bash's programmable completion system. + ''; + type = types.bool; + }; + + enableGlobalCompInit = mkOption { + default = cfg.enableCompletion; + defaultText = literalExpression "config.${opt.enableCompletion}"; + description = '' + Enable execution of compinit call for all interactive zsh shells. + + This option can be disabled if the user wants to extend its + <literal>fpath</literal> and a custom <literal>compinit</literal> + call in the local config is required. + ''; + type = types.bool; + }; + + }; + + }; + + config = mkIf cfg.enable { + + programs.zsh.shellAliases = mapAttrs (name: mkDefault) cfge.shellAliases; + + environment.etc.zshenv.text = + '' + # /etc/zshenv: DO NOT EDIT -- this file has been generated automatically. + # This file is read for all shells. + + # Only execute this file once per shell. + if [ -n "$__ETC_ZSHENV_SOURCED" ]; then return; fi + __ETC_ZSHENV_SOURCED=1 + + if [ -z "$__NIXOS_SET_ENVIRONMENT_DONE" ]; then + . ${config.system.build.setEnvironment} + fi + + HELPDIR="${pkgs.zsh}/share/zsh/$ZSH_VERSION/help" + + # Tell zsh how to find installed completions. + for p in ''${(z)NIX_PROFILES}; do + fpath+=($p/share/zsh/site-functions $p/share/zsh/$ZSH_VERSION/functions $p/share/zsh/vendor-completions) + done + + # Setup custom shell init stuff. + ${cfge.shellInit} + + ${cfg.shellInit} + + # Read system-wide modifications. + if test -f /etc/zshenv.local; then + . /etc/zshenv.local + fi + ''; + + environment.etc.zprofile.text = + '' + # /etc/zprofile: DO NOT EDIT -- this file has been generated automatically. + # This file is read for login shells. + # + ${zshStartupNotes} + + # Only execute this file once per shell. + if [ -n "$__ETC_ZPROFILE_SOURCED" ]; then return; fi + __ETC_ZPROFILE_SOURCED=1 + + # Setup custom login shell init stuff. + ${cfge.loginShellInit} + + ${cfg.loginShellInit} + + # Read system-wide modifications. + if test -f /etc/zprofile.local; then + . /etc/zprofile.local + fi + ''; + + environment.etc.zshrc.text = + '' + # /etc/zshrc: DO NOT EDIT -- this file has been generated automatically. + # This file is read for interactive shells. + # + ${zshStartupNotes} + + # Only execute this file once per shell. + if [ -n "$__ETC_ZSHRC_SOURCED" -o -n "$NOSYSZSHRC" ]; then return; fi + __ETC_ZSHRC_SOURCED=1 + + ${optionalString (cfg.setOptions != []) '' + # Set zsh options. + setopt ${concatStringsSep " " cfg.setOptions} + ''} + + # Setup command line history. + # Don't export these, otherwise other shells (bash) will try to use same HISTFILE. + SAVEHIST=${toString cfg.histSize} + HISTSIZE=${toString cfg.histSize} + HISTFILE=${cfg.histFile} + + # Configure sane keyboard defaults. + . /etc/zinputrc + + ${optionalString cfg.enableGlobalCompInit '' + # Enable autocompletion. + autoload -U compinit && compinit + ''} + + ${optionalString cfg.enableBashCompletion '' + # Enable compatibility with bash's completion system. + autoload -U bashcompinit && bashcompinit + ''} + + # Setup custom interactive shell init stuff. + ${cfge.interactiveShellInit} + + ${cfg.interactiveShellInit} + + # Setup aliases. + ${zshAliases} + + # Setup prompt. + ${cfg.promptInit} + + # Disable some features to support TRAMP. + if [ "$TERM" = dumb ]; then + unsetopt zle prompt_cr prompt_subst + unset RPS1 RPROMPT + PS1='$ ' + PROMPT='$ ' + fi + + # Read system-wide modifications. + if test -f /etc/zshrc.local; then + . /etc/zshrc.local + fi + ''; + + # Bug in nix flakes: + # If we use `.source` here the path is garbage collected also we point to it with a symlink + # see https://github.com/NixOS/nixpkgs/issues/132732 + environment.etc.zinputrc.text = builtins.readFile ./zinputrc; + + environment.systemPackages = [ pkgs.zsh ] + ++ optional cfg.enableCompletion pkgs.nix-zsh-completions; + + environment.pathsToLink = optional cfg.enableCompletion "/share/zsh"; + + #users.defaultUserShell = mkDefault "/run/current-system/sw/bin/zsh"; + + environment.shells = + [ + "/run/current-system/sw/bin/zsh" + "${pkgs.zsh}/bin/zsh" + ]; + + }; + +} |