From de8463dd3ef259502b937fac37fadd6adc252bfe Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Thu, 5 Jun 2025 21:11:35 -0500 Subject: [PATCH] zsh: add plugins.*.completions paths to fpath (#7197) Autocompletion scripts and additional plugin functions are located in specific directories that might not match the plugin source script but need to be included in fpath before calling compinit. An option to provide a path to these scripts is added to add the paths to fpath before calling completionInit. Co-authored-by: @zimeg --- modules/programs/zsh.nix | 40 +++++++++++++++++--------- tests/modules/programs/zsh/default.nix | 1 + tests/modules/programs/zsh/plugins.nix | 31 ++++++++++++++++++++ 3 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 tests/modules/programs/zsh/plugins.nix diff --git a/modules/programs/zsh.nix b/modules/programs/zsh.nix index a99cfdb9..9239849e 100644 --- a/modules/programs/zsh.nix +++ b/modules/programs/zsh.nix @@ -183,15 +183,22 @@ in type = types.str; description = '' The name of the plugin. - - Don't forget to add {option}`file` - if the script name does not follow convention. ''; }; file = mkOption { type = types.str; - description = "The plugin script to source."; + description = '' + The plugin script to source. + Required if the script name does not match {file}`name.plugin.zsh` + using the plugin {option}`name` from the plugin {option}`src`. + ''; + }; + + completions = mkOption { + default = [ ]; + type = types.listOf types.str; + description = "Paths of additional functions to add to {env}`fpath`."; }; }; @@ -605,16 +612,6 @@ in default = [ ]; example = literalExpression '' [ - { - # will source zsh-autosuggestions.plugin.zsh - name = "zsh-autosuggestions"; - src = pkgs.fetchFromGitHub { - owner = "zsh-users"; - repo = "zsh-autosuggestions"; - rev = "v0.4.0"; - sha256 = "0z6i9wjjklb4lvr7zjhbphibsyx51psv50gm07mbb0kj9058j6kc"; - }; - } { name = "enhancd"; file = "init.sh"; @@ -625,6 +622,12 @@ in sha256 = "0iqa9j09fwm6nj5rpip87x3hnvbbz9w9ajgm6wkrd5fls8fn8i5g"; }; } + { + name = "wd"; + src = pkgs.zsh-wd; + file = "share/wd/wd.plugin.zsh"; + completions = [ "share/zsh/site-functions" ]; + } ] ''; description = "Plugins to source in {file}`.zshrc`."; @@ -773,6 +776,15 @@ in map (plugin: '' path+="$HOME/${pluginsDir}/${plugin.name}" fpath+="$HOME/${pluginsDir}/${plugin.name}" + ${ + (optionalString (plugin.completions != [ ]) '' + fpath+=(${ + lib.concatMapStringsSep " " ( + completion: "\"$HOME/${pluginsDir}/${plugin.name}/${completion}\"" + ) plugin.completions + }) + '') + } '') cfg.plugins ) ) diff --git a/tests/modules/programs/zsh/default.nix b/tests/modules/programs/zsh/default.nix index 0e65a4ba..072c8727 100644 --- a/tests/modules/programs/zsh/default.nix +++ b/tests/modules/programs/zsh/default.nix @@ -7,6 +7,7 @@ zsh-history-path-old-custom = ./history-path-old-custom.nix; zsh-history-path-old-default = ./history-path-old-default.nix; zsh-history-substring-search = ./history-substring-search.nix; + zsh-plugins = ./plugins.nix; zsh-prezto = ./prezto.nix; zsh-session-variables = ./session-variables.nix; zsh-syntax-highlighting = ./syntax-highlighting.nix; diff --git a/tests/modules/programs/zsh/plugins.nix b/tests/modules/programs/zsh/plugins.nix new file mode 100644 index 00000000..658a9b5b --- /dev/null +++ b/tests/modules/programs/zsh/plugins.nix @@ -0,0 +1,31 @@ +{ pkgs, ... }: + +let + mockZshPluginSrc = pkgs.writeText "mockZshPluginSrc" "echo example"; +in +{ + config = { + programs.zsh = { + enable = true; + plugins = [ + { + name = "mockPlugin"; + file = "share/mockPlugin/mockPlugin.plugin.zsh"; + src = mockZshPluginSrc; + completions = [ + "share/zsh/site-functions" + "share/zsh/vendor-completions" + ]; + } + ]; + }; + + test.stubs.zsh = { }; + + nmt.script = '' + assertFileRegex home-files/.zshrc '^path+="$HOME/.zsh/plugins/mockPlugin"$' + assertFileRegex home-files/.zshrc '^fpath+="$HOME/.zsh/plugins/mockPlugin"$' + assertFileRegex home-files/.zshrc '^fpath+=("$HOME/.zsh/plugins/mockPlugin/share/zsh/site-functions" "$HOME/.zsh/plugins/mockPlugin/share/zsh/vendor-completions")$' + ''; + }; +}