diff --git a/modules/programs/zsh/plugins/default.nix b/modules/programs/zsh/plugins/default.nix index 5da6461f2..06f5179b6 100644 --- a/modules/programs/zsh/plugins/default.nix +++ b/modules/programs/zsh/plugins/default.nix @@ -102,31 +102,43 @@ in initContent = lib.mkMerge [ (lib.mkOrder 560 ( - lib.concatStrings ( - map (plugin: '' - path+="${pluginsDir}/${plugin.name}" - fpath+="${pluginsDir}/${plugin.name}" - ${ - (lib.optionalString (plugin.completions != [ ]) '' - fpath+=(${ - lib.concatMapStringsSep " " ( - completion: "\"${pluginsDir}/${plugin.name}/${completion}\"" - ) plugin.completions - }) - '') - } - '') cfg.plugins - ) + let + pluginNames = map (plugin: plugin.name) cfg.plugins; + completionPaths = lib.flatten ( + map (plugin: map (completion: "${plugin.name}/${completion}") plugin.completions) cfg.plugins + ); + in + '' + # Add plugin directories to PATH and fpath + ${lib.hm.zsh.define "plugin_dirs" pluginNames} + for plugin_dir in "''${plugin_dirs[@]}"; do + path+="${pluginsDir}/$plugin_dir" + fpath+="${pluginsDir}/$plugin_dir" + done + unset plugin_dir plugin_dirs + ${lib.optionalString (completionPaths != [ ]) '' + # Add completion paths to fpath + ${lib.hm.zsh.define "completion_paths" completionPaths} + for completion_path in "''${completion_paths[@]}"; do + fpath+="${pluginsDir}/$completion_path" + done + unset completion_path completion_paths + ''} + '' )) (lib.mkOrder 900 ( - lib.concatStrings ( - map (plugin: '' - if [[ -f "${pluginsDir}/${plugin.name}/${plugin.file}" ]]; then - source "${pluginsDir}/${plugin.name}/${plugin.file}" - fi - '') cfg.plugins - ) + let + pluginPaths = map (plugin: "${plugin.name}/${plugin.file}") cfg.plugins; + in + '' + # Source plugins + ${lib.hm.zsh.define "plugins" pluginPaths} + for plugin in "''${plugins[@]}"; do + [[ -f "${pluginsDir}/$plugin" ]] && source "${pluginsDir}/$plugin" + done + unset plugin plugins + '' )) ]; }; diff --git a/tests/modules/programs/zsh/history-substring-search-expected.zshrc b/tests/modules/programs/zsh/history-substring-search-expected.zshrc new file mode 100644 index 000000000..a73c04322 --- /dev/null +++ b/tests/modules/programs/zsh/history-substring-search-expected.zshrc @@ -0,0 +1,57 @@ +typeset -U path cdpath fpath manpath +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="@zsh@/share/zsh/$ZSH_VERSION/help" + +autoload -U compinit && compinit +# History options should be set in .zshrc and after oh-my-zsh sourcing. +# See https://github.com/nix-community/home-manager/issues/177. +HISTSIZE="10000" +SAVEHIST="10000" + +HISTFILE="/home/hm-user/.zsh_history" +mkdir -p "$(dirname "$HISTFILE")" + +setopt HIST_FCNTL_LOCK + +# Enabled history options +enabled_opts=( + HIST_IGNORE_DUPS HIST_IGNORE_SPACE SHARE_HISTORY +) +for opt in "${enabled_opts[@]}"; do + setopt "$opt" +done +unset opt enabled_opts + +# Disabled history options +disabled_opts=( + APPEND_HISTORY EXTENDED_HISTORY HIST_EXPIRE_DUPS_FIRST HIST_FIND_NO_DUPS + HIST_IGNORE_ALL_DUPS HIST_SAVE_NO_DUPS +) +for opt in "${disabled_opts[@]}"; do + unsetopt "$opt" +done +unset opt disabled_opts + +source @zsh-history-substring-search@/share/zsh-history-substring-search/zsh-history-substring-search.zsh + +# Bind search up keys +search_up_keys=( + '^[[A' '\eOA' +) + for key in "${search_up_keys[@]}"; do + bindkey "$key" history-substring-search-up + done + unset key search_up_keys + +# Bind search down keys +search_down_keys=( + '^[[B' +) + for key in "${search_down_keys[@]}"; do + bindkey "$key" history-substring-search-down + done + unset key search_down_keys + diff --git a/tests/modules/programs/zsh/history-substring-search.nix b/tests/modules/programs/zsh/history-substring-search.nix index 5fe204c61..9232bc9c4 100644 --- a/tests/modules/programs/zsh/history-substring-search.nix +++ b/tests/modules/programs/zsh/history-substring-search.nix @@ -11,10 +11,8 @@ }; }; - # Written with regex to ensure we don't end up missing newlines in the future nmt.script = '' - assertFileRegex home-files/.zshrc "^bindkey \"\^\[\[B\" history-substring-search-down$" - assertFileRegex home-files/.zshrc "^bindkey \"\^\[\[A\" history-substring-search-up$" - assertFileRegex home-files/.zshrc "^bindkey \"\\\\eOA\" history-substring-search-up$" + assertFileExists home-files/.zshrc + assertFileContent $(normalizeStorePaths home-files/.zshrc) ${./history-substring-search-expected.zshrc} ''; } diff --git a/tests/modules/programs/zsh/plugins.nix b/tests/modules/programs/zsh/plugins.nix index 4756be3ef..d69b8095f 100644 --- a/tests/modules/programs/zsh/plugins.nix +++ b/tests/modules/programs/zsh/plugins.nix @@ -23,9 +23,29 @@ in test.stubs.zsh = { }; nmt.script = '' - assertFileRegex home-files/.zshrc '^path+="/home/hm-user/.zsh/plugins/mockPlugin"$' - assertFileRegex home-files/.zshrc '^fpath+="/home/hm-user/.zsh/plugins/mockPlugin"$' - assertFileRegex home-files/.zshrc '^fpath+=("/home/hm-user/.zsh/plugins/mockPlugin/share/zsh/site-functions" "/home/hm-user/.zsh/plugins/mockPlugin/share/zsh/vendor-completions")$' + # Test the plugin directories loop structure + assertFileContains home-files/.zshrc '# Add plugin directories to PATH and fpath' + assertFileContains home-files/.zshrc 'plugin_dirs=(' + assertFileContains home-files/.zshrc 'mockPlugin' + assertFileContains home-files/.zshrc 'for plugin_dir in "''${plugin_dirs[@]}"; do' + assertFileContains home-files/.zshrc 'path+="/home/hm-user/.zsh/plugins/$plugin_dir"' + assertFileContains home-files/.zshrc 'fpath+="/home/hm-user/.zsh/plugins/$plugin_dir"' + + # Test the completion paths loop structure + assertFileContains home-files/.zshrc '# Add completion paths to fpath' + assertFileContains home-files/.zshrc 'completion_paths=(' + assertFileContains home-files/.zshrc 'mockPlugin/share/zsh/site-functions' + assertFileContains home-files/.zshrc 'mockPlugin/share/zsh/vendor-completions' + assertFileContains home-files/.zshrc 'for completion_path in "''${completion_paths[@]}"; do' + assertFileContains home-files/.zshrc 'fpath+="/home/hm-user/.zsh/plugins/$completion_path"' + + # Test the plugin loading structure + assertFileContains home-files/.zshrc '# Source plugins' + assertFileContains home-files/.zshrc 'plugins=(' + assertFileContains home-files/.zshrc 'mockPlugin/share/mockPlugin/mockPlugin.plugin.zsh' + assertFileContains home-files/.zshrc 'for plugin in "''${plugins[@]}"; do' + assertFileContains home-files/.zshrc '[[ -f "/home/hm-user/.zsh/plugins/$plugin" ]] && source "/home/hm-user/.zsh/plugins/$plugin"' + assertFileContains home-files/.zshrc 'done' ''; }; }