1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-11-09 12:06:04 +01:00

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

* zsh: add initContent option for custom .zshrc content insertion

- Users can add content anywhere by using `lib.mkOrder`, `lib.mkBefore`
and `lib.mkAfter` custom configurations.
- Add test cases to verify the insertion of content before and after
existing configurations in `.zshrc`.
consolidate zshrc content tests into a single priorities test
This commit is contained in:
Qiming Chu 2025-03-13 21:37:11 +08:00 committed by GitHub
parent 1878091234
commit 7832b5aa95
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 177 additions and 117 deletions

View file

@ -2129,6 +2129,17 @@ in {
Cohere, Groq). Cohere, Groq).
''; '';
} }
{
time = "2025-03-11T02:34:43+00:00";
condition = config.programs.zsh.enable;
message = ''
A new module is available: 'programs.zsh.initContent'.
initContent option allows you to set the content of the zshrc file,
you can use `lib.mkOrder` to specify the order of the content you want to insert.
'';
}
]; ];
}; };
} }

View file

@ -471,6 +471,15 @@ in
description = "Environment variables that will be set for zsh session."; description = "Environment variables that will be set for zsh session.";
}; };
initContent = mkOption {
default = "";
type = types.lines;
example = lib.mkOrder 1000 ''
echo "Hello, initContent!"
'';
description = "Content to be added to {file}`.zshrc`. To specify the order, use `lib.mkOrder`.";
};
initExtraBeforeCompInit = mkOption { initExtraBeforeCompInit = mkOption {
default = ""; default = "";
type = types.lines; type = types.lines;
@ -616,79 +625,76 @@ in
++ optional cfg.enableCompletion pkgs.nix-zsh-completions ++ optional cfg.enableCompletion pkgs.nix-zsh-completions
++ optional cfg.oh-my-zsh.enable cfg.oh-my-zsh.package; ++ optional cfg.oh-my-zsh.enable cfg.oh-my-zsh.package;
home.file."${relToDotDir ".zshrc"}".text = concatStringsSep "\n" ([ programs.zsh.initContent = mkMerge [
# zprof must be loaded before everything else, since it # zprof must be loaded before everything else, since it
# benchmarks the shell initialization. # benchmarks the shell initialization.
(optionalString cfg.zprof.enable '' (mkOrder 400 (optionalString cfg.zprof.enable ''
zmodload zsh/zprof zmodload zsh/zprof
'') ''))
cfg.initExtraFirst (mkOrder 550 cfg.initExtraFirst)
"typeset -U path cdpath fpath manpath" (mkOrder 600 "typeset -U path cdpath fpath manpath")
(optionalString (cfg.cdpath != []) '' (mkOrder 650 (optionalString (cfg.cdpath != [ ]) ''
cdpath+=(${concatStringsSep " " cfg.cdpath}) cdpath+=(${concatStringsSep " " cfg.cdpath})
'') ''))
(mkOrder 700 ''
''
for profile in ''${(z)NIX_PROFILES}; do for profile in ''${(z)NIX_PROFILES}; do
fpath+=($profile/share/zsh/site-functions $profile/share/zsh/$ZSH_VERSION/functions $profile/share/zsh/vendor-completions) fpath+=($profile/share/zsh/site-functions $profile/share/zsh/$ZSH_VERSION/functions $profile/share/zsh/vendor-completions)
done 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. # Use ${cfg.defaultKeymap} keymap as the default.
${getAttr cfg.defaultKeymap bindkeyCommands} ${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}" path+="$HOME/${pluginsDir}/${plugin.name}"
fpath+="$HOME/${pluginsDir}/${plugin.name}" fpath+="$HOME/${pluginsDir}/${plugin.name}"
'') cfg.plugins)) '') cfg.plugins)))
'' (mkOrder 950 ''
# Oh-My-Zsh/Prezto calls compinit during initialization, # Oh-My-Zsh/Prezto calls compinit during initialization,
# calling it twice causes slight start up slowdown # calling it twice causes slight start up slowdown
# as all $fpath entries will be traversed again. # as all $fpath entries will be traversed again.
${optionalString (cfg.enableCompletion && !cfg.oh-my-zsh.enable && !cfg.prezto.enable) ${optionalString
cfg.completionInit (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 source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh
${optionalString (cfg.autosuggestion.strategy != []) '' ${optionalString (cfg.autosuggestion.strategy != [ ]) ''
ZSH_AUTOSUGGEST_STRATEGY=(${concatStringsSep " " cfg.autosuggestion.strategy}) ZSH_AUTOSUGGEST_STRATEGY=(${
'' concatStringsSep " " cfg.autosuggestion.strategy
} })
'') ''}
(optionalString (cfg.autosuggestion.enable && cfg.autosuggestion.highlight != null) '' ''))
(mkOrder 1050 (optionalString
(cfg.autosuggestion.enable && cfg.autosuggestion.highlight != null) ''
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="${cfg.autosuggestion.highlight}" ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="${cfg.autosuggestion.highlight}"
'') ''))
(optionalString cfg.oh-my-zsh.enable '' (mkOrder 1100 (optionalString cfg.oh-my-zsh.enable ''
# oh-my-zsh extra settings for plugins # oh-my-zsh extra settings for plugins
${cfg.oh-my-zsh.extraConfig} ${cfg.oh-my-zsh.extraConfig}
# oh-my-zsh configuration generated by NixOS # oh-my-zsh configuration generated by NixOS
${optionalString (cfg.oh-my-zsh.plugins != []) ${optionalString (cfg.oh-my-zsh.plugins != [ ])
"plugins=(${concatStringsSep " " cfg.oh-my-zsh.plugins})" "plugins=(${concatStringsSep " " cfg.oh-my-zsh.plugins})"}
}
${optionalString (cfg.oh-my-zsh.custom != "") ${optionalString (cfg.oh-my-zsh.custom != "")
"ZSH_CUSTOM=\"${cfg.oh-my-zsh.custom}\"" ''ZSH_CUSTOM="${cfg.oh-my-zsh.custom}"''}
}
${optionalString (cfg.oh-my-zsh.theme != "") ${optionalString (cfg.oh-my-zsh.theme != "")
"ZSH_THEME=\"${cfg.oh-my-zsh.theme}\"" ''ZSH_THEME="${cfg.oh-my-zsh.theme}"''}
}
source $ZSH/oh-my-zsh.sh source $ZSH/oh-my-zsh.sh
'') ''))
(mkOrder 1150 ''
'' ${optionalString cfg.prezto.enable (builtins.readFile
${optionalString cfg.prezto.enable "${cfg.prezto.package}/share/zsh-prezto/runcoms/zshrc")}
(builtins.readFile "${cfg.prezto.package}/share/zsh-prezto/runcoms/zshrc")}
${concatStrings (map (plugin: '' ${concatStrings (map (plugin: ''
if [[ -f "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" ]]; then if [[ -f "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" ]]; then
@ -700,10 +706,15 @@ in
# See https://github.com/nix-community/home-manager/issues/177. # See https://github.com/nix-community/home-manager/issues/177.
HISTSIZE="${toString cfg.history.size}" HISTSIZE="${toString cfg.history.size}"
SAVEHIST="${toString cfg.history.save}" SAVEHIST="${toString cfg.history.save}"
${optionalString (cfg.history.ignorePatterns != []) "HISTORY_IGNORE=${lib.escapeShellArg "(${lib.concatStringsSep "|" cfg.history.ignorePatterns})"}"} ${optionalString (cfg.history.ignorePatterns != [ ])
${if versionAtLeast config.home.stateVersion "20.03" "HISTORY_IGNORE=${
then ''HISTFILE="${cfg.history.path}"'' lib.escapeShellArg
else ''HISTFILE="$HOME/${cfg.history.path}"''} "(${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")" mkdir -p "$(dirname "$HISTFILE")"
setopt HIST_FCNTL_LOCK setopt HIST_FCNTL_LOCK
@ -717,20 +728,21 @@ in
${if cfg.history.share then "setopt" else "unsetopt"} SHARE_HISTORY ${if cfg.history.share then "setopt" else "unsetopt"} SHARE_HISTORY
${if cfg.history.extended then "setopt" else "unsetopt"} EXTENDED_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 ""} ${if cfg.autocd != null then "${if cfg.autocd then "setopt" else "unsetopt"} autocd" else ""}
'')
${cfg.initExtra} (mkOrder 1200 cfg.initExtra)
# Aliases # Aliases
${aliasesStr} (mkOrder 1250 aliasesStr)
'' (mkOrder 1250 (concatStringsSep "\n" (mapAttrsToList
] (k: v: "alias -g -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}")
++ (mapAttrsToList (k: v: "alias -g -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}") cfg.shellGlobalAliases) cfg.shellGlobalAliases)))
++ [ ('' (mkOrder 1300 ''
# Named Directory Hashes # Named Directory Hashes
${dirHashesStr} ${dirHashesStr}
'') '')
(optionalString cfg.syntaxHighlighting.enable (mkOrder 1350 (optionalString cfg.syntaxHighlighting.enable
# Load zsh-syntax-highlighting after all custom widgets have been created # Load zsh-syntax-highlighting after all custom widgets have been created
# https://github.com/zsh-users/zsh-syntax-highlighting#faq # https://github.com/zsh-users/zsh-syntax-highlighting#faq
'' ''
@ -746,28 +758,28 @@ in
(name: value: "ZSH_HIGHLIGHT_PATTERNS+=(${lib.escapeShellArg name} ${lib.escapeShellArg value})") (name: value: "ZSH_HIGHLIGHT_PATTERNS+=(${lib.escapeShellArg name} ${lib.escapeShellArg value})")
cfg.syntaxHighlighting.patterns cfg.syntaxHighlighting.patterns
)} )}
'') ''))
(optionalString (cfg.historySubstringSearch.enable or false) (mkOrder 1400 (optionalString
(cfg.historySubstringSearch.enable or false)
# Load zsh-history-substring-search after zsh-syntax-highlighting # Load zsh-history-substring-search after zsh-syntax-highlighting
# https://github.com/zsh-users/zsh-history-substring-search#usage # 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 source ${pkgs.zsh-history-substring-search}/share/zsh-history-substring-search/zsh-history-substring-search.zsh
${lib.concatMapStringsSep "\n" ${lib.concatMapStringsSep "\n"
(upKey: "bindkey \"${upKey}\" history-substring-search-up") (upKey: ''bindkey "${upKey}" history-substring-search-up'')
(lib.toList cfg.historySubstringSearch.searchUpKey) (lib.toList cfg.historySubstringSearch.searchUpKey)}
}
${lib.concatMapStringsSep "\n" ${lib.concatMapStringsSep "\n"
(downKey: "bindkey \"${downKey}\" history-substring-search-down") (downKey: ''bindkey "${downKey}" history-substring-search-down'')
(lib.toList cfg.historySubstringSearch.searchDownKey) (lib.toList cfg.historySubstringSearch.searchDownKey)}
} ''))
'')
(optionalString cfg.zprof.enable (mkOrder 1450 (optionalString cfg.zprof.enable ''
''
zprof zprof
'') ''))
]); ];
home.file."${relToDotDir ".zshrc"}".text = cfg.initContent;
} }
(mkIf cfg.oh-my-zsh.enable { (mkIf cfg.oh-my-zsh.enable {

View file

@ -9,4 +9,5 @@
zsh-prezto = ./prezto.nix; zsh-prezto = ./prezto.nix;
zsh-syntax-highlighting = ./syntax-highlighting.nix; zsh-syntax-highlighting = ./syntax-highlighting.nix;
zsh-abbr = ./zsh-abbr.nix; zsh-abbr = ./zsh-abbr.nix;
zshrc-contents-priorities = ./zshrc-content-priorities.nix;
} }

View file

@ -0,0 +1,36 @@
{ lib, ... }: {
programs.zsh = {
enable = true;
initContent = lib.mkMerge [
(lib.mkBefore ''
# High priority (mkBefore)
echo "High priority content"
'')
(lib.mkAfter ''
# Low priority (mkAfter)
echo "Low priority content"
'')
''
# Default priority
echo "Default priority content"
''
];
zprof.enable = true;
};
nmt.script = ''
assertFileExists home-files/.zshrc
assertFileContains home-files/.zshrc "zmodload zsh/zprof"
assertFileContains home-files/.zshrc "High priority content"
assertFileContains home-files/.zshrc "Default priority content"
assertFileContains home-files/.zshrc "Low priority content"
assertFileRegex home-files/.zshrc '^zmodload zsh/zprof'
assertFileRegex home-files/.zshrc 'echo "Low priority content"$'
'';
}