Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zsh: refactor zsh configuration for better order control over .zshrc #6479

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
252 changes: 127 additions & 125 deletions modules/programs/zsh.nix
Original file line number Diff line number Diff line change
Expand Up @@ -616,158 +616,160 @@ in
++ optional cfg.enableCompletion pkgs.nix-zsh-completions
++ optional cfg.oh-my-zsh.enable cfg.oh-my-zsh.package;

home.file."${relToDotDir ".zshrc"}".text = concatStringsSep "\n" ([
programs.zsh.initExtra = mkMerge [
# zprof must be loaded before everything else, since it
# benchmarks the shell initialization.
(optionalString cfg.zprof.enable ''
(mkOrder 500 (optionalString cfg.zprof.enable ''
zmodload zsh/zprof
'')
''))

cfg.initExtraFirst
"typeset -U path cdpath fpath manpath"
(mkOrder 550 cfg.initExtraFirst)
(mkOrder 600 "typeset -U path cdpath fpath manpath")

(optionalString (cfg.cdpath != []) ''
(mkOrder 650 (optionalString (cfg.cdpath != [ ]) ''
cdpath+=(${concatStringsSep " " cfg.cdpath})
'')

''
for profile in ''${(z)NIX_PROFILES}; do
fpath+=($profile/share/zsh/site-functions $profile/share/zsh/$ZSH_VERSION/functions $profile/share/zsh/vendor-completions)
done
''))
(mkOrder 700 ''
for profile in ''${(z)NIX_PROFILES}; do
fpath+=($profile/share/zsh/site-functions $profile/share/zsh/$ZSH_VERSION/functions $profile/share/zsh/vendor-completions)
done

HELPDIR="${cfg.package}/share/zsh/$ZSH_VERSION/help"
''
HELPDIR="${cfg.package}/share/zsh/$ZSH_VERSION/help"
'')

(optionalString (cfg.defaultKeymap != null) ''
(mkOrder 750 (optionalString (cfg.defaultKeymap != null) ''
# Use ${cfg.defaultKeymap} keymap as the default.
${getAttr cfg.defaultKeymap bindkeyCommands}
'')
localVarsStr
''))

cfg.initExtraBeforeCompInit
(mkOrder 800 localVarsStr)
(mkOrder 850 cfg.initExtraBeforeCompInit)

(concatStrings (map (plugin: ''
(mkOrder 900 (concatStrings (map (plugin: ''
path+="$HOME/${pluginsDir}/${plugin.name}"
fpath+="$HOME/${pluginsDir}/${plugin.name}"
'') cfg.plugins))
'') cfg.plugins)))

''
# Oh-My-Zsh/Prezto calls compinit during initialization,
# calling it twice causes slight start up slowdown
# as all $fpath entries will be traversed again.
${optionalString (cfg.enableCompletion && !cfg.oh-my-zsh.enable && !cfg.prezto.enable)
cfg.completionInit
}''
(mkOrder 950 ''
# Oh-My-Zsh/Prezto calls compinit during initialization,
# calling it twice causes slight start up slowdown
# as all $fpath entries will be traversed again.
${optionalString
(cfg.enableCompletion && !cfg.oh-my-zsh.enable && !cfg.prezto.enable)
cfg.completionInit}'')

(optionalString cfg.autosuggestion.enable ''
(mkOrder 1000 (optionalString cfg.autosuggestion.enable ''
source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh
${optionalString (cfg.autosuggestion.strategy != []) ''
ZSH_AUTOSUGGEST_STRATEGY=(${concatStringsSep " " cfg.autosuggestion.strategy})
''
}
'')
(optionalString (cfg.autosuggestion.enable && cfg.autosuggestion.highlight != null) ''
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="${cfg.autosuggestion.highlight}"
'')

(optionalString cfg.oh-my-zsh.enable ''
# oh-my-zsh extra settings for plugins
${cfg.oh-my-zsh.extraConfig}
# oh-my-zsh configuration generated by NixOS
${optionalString (cfg.oh-my-zsh.plugins != [])
"plugins=(${concatStringsSep " " cfg.oh-my-zsh.plugins})"
}
${optionalString (cfg.oh-my-zsh.custom != "")
"ZSH_CUSTOM=\"${cfg.oh-my-zsh.custom}\""
}
${optionalString (cfg.oh-my-zsh.theme != "")
"ZSH_THEME=\"${cfg.oh-my-zsh.theme}\""
}
source $ZSH/oh-my-zsh.sh
${optionalString (cfg.autosuggestion.strategy != [ ]) ''
ZSH_AUTOSUGGEST_STRATEGY=(${
concatStringsSep " " cfg.autosuggestion.strategy
})
''}
''))
(mkOrder 1050 (optionalString
(cfg.autosuggestion.enable && cfg.autosuggestion.highlight != null) ''
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="${cfg.autosuggestion.highlight}"
''))

(mkOrder 1100 (optionalString cfg.oh-my-zsh.enable ''
# oh-my-zsh extra settings for plugins
${cfg.oh-my-zsh.extraConfig}
# oh-my-zsh configuration generated by NixOS
${optionalString (cfg.oh-my-zsh.plugins != [ ])
"plugins=(${concatStringsSep " " cfg.oh-my-zsh.plugins})"}
${optionalString (cfg.oh-my-zsh.custom != "")
''ZSH_CUSTOM="${cfg.oh-my-zsh.custom}"''}
${optionalString (cfg.oh-my-zsh.theme != "")
''ZSH_THEME="${cfg.oh-my-zsh.theme}"''}
source $ZSH/oh-my-zsh.sh
''))
(mkOrder 1150 ''
${optionalString cfg.prezto.enable (builtins.readFile
"${cfg.prezto.package}/share/zsh-prezto/runcoms/zshrc")}

${concatStrings (map (plugin: ''
if [[ -f "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" ]]; then
source "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}"
fi
'') cfg.plugins)}

# History options should be set in .zshrc and after oh-my-zsh sourcing.
# See https://github.com/nix-community/home-manager/issues/177.
HISTSIZE="${toString cfg.history.size}"
SAVEHIST="${toString cfg.history.save}"
${optionalString (cfg.history.ignorePatterns != [ ])
"HISTORY_IGNORE=${
lib.escapeShellArg
"(${lib.concatStringsSep "|" cfg.history.ignorePatterns})"
}"}
${if versionAtLeast config.home.stateVersion "20.03" then
''HISTFILE="${cfg.history.path}"''
else
''HISTFILE="$HOME/${cfg.history.path}"''}
mkdir -p "$(dirname "$HISTFILE")"

setopt HIST_FCNTL_LOCK
${if cfg.history.append then "setopt" else "unsetopt"} APPEND_HISTORY
${if cfg.history.ignoreDups then "setopt" else "unsetopt"} HIST_IGNORE_DUPS
${if cfg.history.ignoreAllDups then "setopt" else "unsetopt"} HIST_IGNORE_ALL_DUPS
${if cfg.history.saveNoDups then "setopt" else "unsetopt"} HIST_SAVE_NO_DUPS
${if cfg.history.findNoDups then "setopt" else "unsetopt"} HIST_FIND_NO_DUPS
${if cfg.history.ignoreSpace then "setopt" else "unsetopt"} HIST_IGNORE_SPACE
${if cfg.history.expireDuplicatesFirst then "setopt" else "unsetopt"} HIST_EXPIRE_DUPS_FIRST
${if cfg.history.share then "setopt" else "unsetopt"} SHARE_HISTORY
${if cfg.history.extended then "setopt" else "unsetopt"} EXTENDED_HISTORY
${if cfg.autocd != null then "${if cfg.autocd then "setopt" else "unsetopt"} autocd" else ""}
'')

''
${optionalString cfg.prezto.enable
(builtins.readFile "${cfg.prezto.package}/share/zsh-prezto/runcoms/zshrc")}

${concatStrings (map (plugin: ''
if [[ -f "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" ]]; then
source "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}"
fi
'') cfg.plugins)}

# History options should be set in .zshrc and after oh-my-zsh sourcing.
# See https://github.com/nix-community/home-manager/issues/177.
HISTSIZE="${toString cfg.history.size}"
SAVEHIST="${toString cfg.history.save}"
${optionalString (cfg.history.ignorePatterns != []) "HISTORY_IGNORE=${lib.escapeShellArg "(${lib.concatStringsSep "|" cfg.history.ignorePatterns})"}"}
${if versionAtLeast config.home.stateVersion "20.03"
then ''HISTFILE="${cfg.history.path}"''
else ''HISTFILE="$HOME/${cfg.history.path}"''}
mkdir -p "$(dirname "$HISTFILE")"

setopt HIST_FCNTL_LOCK
${if cfg.history.append then "setopt" else "unsetopt"} APPEND_HISTORY
${if cfg.history.ignoreDups then "setopt" else "unsetopt"} HIST_IGNORE_DUPS
${if cfg.history.ignoreAllDups then "setopt" else "unsetopt"} HIST_IGNORE_ALL_DUPS
${if cfg.history.saveNoDups then "setopt" else "unsetopt"} HIST_SAVE_NO_DUPS
${if cfg.history.findNoDups then "setopt" else "unsetopt"} HIST_FIND_NO_DUPS
${if cfg.history.ignoreSpace then "setopt" else "unsetopt"} HIST_IGNORE_SPACE
${if cfg.history.expireDuplicatesFirst then "setopt" else "unsetopt"} HIST_EXPIRE_DUPS_FIRST
${if cfg.history.share then "setopt" else "unsetopt"} SHARE_HISTORY
${if cfg.history.extended then "setopt" else "unsetopt"} EXTENDED_HISTORY
${if cfg.autocd != null then "${if cfg.autocd then "setopt" else "unsetopt"} autocd" else ""}

${cfg.initExtra}

# Aliases
${aliasesStr}
''
]
++ (mapAttrsToList (k: v: "alias -g -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}") cfg.shellGlobalAliases)
++ [ (''
# Named Directory Hashes
${dirHashesStr}
(mkOrder 1250 aliasesStr)
(mkOrder 1250 (concatStringsSep "\n" (mapAttrsToList
(k: v: "alias -g -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}")
cfg.shellGlobalAliases)))
(mkOrder 1300 ''
# Named Directory Hashes
${dirHashesStr}
'')

(optionalString cfg.syntaxHighlighting.enable
(mkOrder 1350 (optionalString cfg.syntaxHighlighting.enable
# Load zsh-syntax-highlighting after all custom widgets have been created
# https://github.com/zsh-users/zsh-syntax-highlighting#faq
''
source ${cfg.syntaxHighlighting.package}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
ZSH_HIGHLIGHT_HIGHLIGHTERS+=(${lib.concatStringsSep " " (map lib.escapeShellArg cfg.syntaxHighlighting.highlighters)})
${lib.concatStringsSep "\n" (
lib.mapAttrsToList
(name: value: "ZSH_HIGHLIGHT_STYLES+=(${lib.escapeShellArg name} ${lib.escapeShellArg value})")
cfg.syntaxHighlighting.styles
)}
${lib.concatStringsSep "\n" (
lib.mapAttrsToList
(name: value: "ZSH_HIGHLIGHT_PATTERNS+=(${lib.escapeShellArg name} ${lib.escapeShellArg value})")
cfg.syntaxHighlighting.patterns
)}
'')

(optionalString (cfg.historySubstringSearch.enable or false)
''
source ${cfg.syntaxHighlighting.package}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
ZSH_HIGHLIGHT_HIGHLIGHTERS+=(${
lib.concatStringsSep " "
(map lib.escapeShellArg cfg.syntaxHighlighting.highlighters)
})
${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value:
"ZSH_HIGHLIGHT_STYLES+=(${lib.escapeShellArg name} ${
lib.escapeShellArg value
})") cfg.syntaxHighlighting.styles)}
${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value:
"ZSH_HIGHLIGHT_PATTERNS+=(${lib.escapeShellArg name} ${
lib.escapeShellArg value
})") cfg.syntaxHighlighting.patterns)}
''))

(mkOrder 1400 (optionalString
(cfg.historySubstringSearch.enable or false)
# Load zsh-history-substring-search after zsh-syntax-highlighting
# https://github.com/zsh-users/zsh-history-substring-search#usage
''
source ${pkgs.zsh-history-substring-search}/share/zsh-history-substring-search/zsh-history-substring-search.zsh
${lib.concatMapStringsSep "\n"
(upKey: "bindkey \"${upKey}\" history-substring-search-up")
(lib.toList cfg.historySubstringSearch.searchUpKey)
}
${lib.concatMapStringsSep "\n"
(downKey: "bindkey \"${downKey}\" history-substring-search-down")
(lib.toList cfg.historySubstringSearch.searchDownKey)
}
'')

(optionalString cfg.zprof.enable
''
''
source ${pkgs.zsh-history-substring-search}/share/zsh-history-substring-search/zsh-history-substring-search.zsh
${lib.concatMapStringsSep "\n"
(upKey: ''bindkey "${upKey}" history-substring-search-up'')
(lib.toList cfg.historySubstringSearch.searchUpKey)}
${lib.concatMapStringsSep "\n"
(downKey: ''bindkey "${downKey}" history-substring-search-down'')
(lib.toList cfg.historySubstringSearch.searchDownKey)}
''))

(mkOrder 1450 (optionalString cfg.zprof.enable ''
zprof
'')
]);
''))
];

home.file."${relToDotDir ".zshrc"}".text = cfg.initExtra;
}

(mkIf cfg.oh-my-zsh.enable {
Expand Down
3 changes: 3 additions & 0 deletions tests/modules/programs/zsh/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@
zsh-prezto = ./prezto.nix;
zsh-syntax-highlighting = ./syntax-highlighting.nix;
zsh-abbr = ./zsh-abbr.nix;
zshrc-contents-insert = ./zshrc-contents-insert.nix;
zshrc-contents-insert-before = ./zshrc-contents-insert-before.nix;
zshrc-contents-insert-after = ./zshrc-contents-insert-after.nix;
}
14 changes: 14 additions & 0 deletions tests/modules/programs/zsh/zshrc-contents-insert-after.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{ lib, ... }: {
programs.zsh = {
enable = true;
initExtra = lib.mkAfter ''
# Custom contents
echo "Custom contents"
'';
};

nmt.script = ''
assertFileExists home-files/.zshrc
assertFileRegex home-files/.zshrc $'# Custom contents\necho "Custom contents"$'
'';
}
14 changes: 14 additions & 0 deletions tests/modules/programs/zsh/zshrc-contents-insert-before.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{ lib, ... }: {
programs.zsh = {
enable = true;
initExtra = lib.mkBefore ''
# Custom contents
echo "Custom contents"
'';
};

nmt.script = ''
assertFileExists home-files/.zshrc
assertFileRegex home-files/.zshrc $'^# Custom contents\necho "Custom contents"'
'';
}
13 changes: 13 additions & 0 deletions tests/modules/programs/zsh/zshrc-contents-insert.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
programs.zsh = {
enable = true;
initExtra = ''
# Custom contents
echo "Custom contents"
'';
};

nmt.script = ''
assertFileContains home-files/.zshrc $'# Custom contents\necho "Custom contents"'
'';
}