This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch backport/zsh-completion-1.x
in repository https://gitbox.apache.org/repos/asf/maven-mvnd.git

commit 28b8fa87ca5a4923a51bc576a2615cec5cc956aa
Author: Guillaume Nodet <[email protected]>
AuthorDate: Tue Mar 17 09:02:45 2026 +0100

    Add zsh support to completion script
    
    Make the existing bash completion script work in both bash and zsh
    by auto-detecting the shell and adapting behavior accordingly:
    
    - Add shell detection via $ZSH_VERSION / $BASH_VERSION
    - Load bashcompinit in zsh for bash-style completion compatibility
    - Use typeset instead of declare/compgen for zsh
    - Use ${(P)var} instead of ${!var} for indirect expansion in zsh
    - Accept 'zsh' as valid --completion argument in Completion.java
    - Update README.adoc with zsh instructions
    
    Based on the approach from PR #1514 by janweinschenker, consolidated
    into the single existing script to avoid duplication.
    
    Co-Authored-By: Jan Weinschenker <[email protected]>
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 README.adoc                                        |  8 +++--
 .../java/org/mvndaemon/mvnd/client/Completion.java |  7 ++--
 .../completion-templates/mvnd-bash-completion.bash | 37 +++++++++++++++++++---
 dist/src/main/distro/bin/mvnd-bash-completion.bash | 37 +++++++++++++++++++---
 4 files changed, 73 insertions(+), 16 deletions(-)

diff --git a/README.adoc b/README.adoc
index f0935afb..a935066d 100644
--- a/README.adoc
+++ b/README.adoc
@@ -105,13 +105,15 @@ $ asdf install mvnd latest
 
 === Set up completion
 
-Optionally, you can set up completion as follows:
+Optionally, you can set up completion in bash or zsh as follows:
 [source,shell]
 ----
-# ensure that MVND_HOME points to your mvnd distribution, note that sdkman 
does it for you
+# bash: ensure that MVND_HOME points to your mvnd distribution, note that 
sdkman does it for you
 $ echo 'source $MVND_HOME/bin/mvnd-bash-completion.bash' >> ~/.bashrc
+
+# zsh: same script works in zsh (it auto-detects the shell)
+$ echo 'source $MVND_HOME/bin/mvnd-bash-completion.bash' >> ~/.zshrc
 ----
-`bash` is the only shell supported at this time.
 
 === Note for oh-my-zsh users ===
 
diff --git a/client/src/main/java/org/mvndaemon/mvnd/client/Completion.java 
b/client/src/main/java/org/mvndaemon/mvnd/client/Completion.java
index f971f82a..40241f1e 100644
--- a/client/src/main/java/org/mvndaemon/mvnd/client/Completion.java
+++ b/client/src/main/java/org/mvndaemon/mvnd/client/Completion.java
@@ -27,12 +27,13 @@ import java.nio.file.Path;
 public class Completion {
 
     public static String getCompletion(String shell, DaemonParameters 
daemonParameters) {
-        if (!"bash".equals(shell)) {
-            throw new IllegalArgumentException("Unexpected --completion value: 
'" + shell + "'; expected: 'bash'");
+        if (!"bash".equals(shell) && !"zsh".equals(shell)) {
+            throw new IllegalArgumentException(
+                    "Unexpected --completion value: '" + shell + "'; expected: 
'bash' or 'zsh'");
         }
         final Path bashCompletionPath = 
daemonParameters.mvndHome().resolve("bin/mvnd-bash-completion.bash");
         if (!Files.isRegularFile(bashCompletionPath)) {
-            throw new IllegalStateException("Bash completion file does not 
exist: " + bashCompletionPath);
+            throw new IllegalStateException("Completion file does not exist: " 
+ bashCompletionPath);
         }
         try {
             return new String(Files.readAllBytes(bashCompletionPath), 
StandardCharsets.UTF_8);
diff --git 
a/client/src/test/resources/completion-templates/mvnd-bash-completion.bash 
b/client/src/test/resources/completion-templates/mvnd-bash-completion.bash
index 95eea34f..5cc83b7e 100644
--- a/client/src/test/resources/completion-templates/mvnd-bash-completion.bash
+++ b/client/src/test/resources/completion-templates/mvnd-bash-completion.bash
@@ -17,10 +17,26 @@
 # Adapted from 
https://github.com/juven/maven-bash-completion/blob/master/bash_completion.bash 
by Juven Xu and others
 # under Apache License Version 2.0
 
+# Detect shell type and set up zsh compatibility if needed
+if [ -n "$ZSH_VERSION" ]; then
+    __MVND_SHELL="zsh"
+    # Load bashcompinit for bash-style completions in zsh
+    autoload -Uz bashcompinit 2>/dev/null && bashcompinit
+    # Define COMP_WORDBREAKS if not set (bash sets this automatically)
+    [[ -z "$COMP_WORDBREAKS" ]] && COMP_WORDBREAKS=$' \t\n"\'><=;|&(:'
+else
+    __MVND_SHELL="bash"
+fi
+
 function_exists()
 {
-    declare -F $1 > /dev/null
-    return $?
+    if [ "$__MVND_SHELL" = "zsh" ]; then
+        typeset -f $1 > /dev/null 2>&1
+        return $?
+    else
+        declare -F $1 > /dev/null
+        return $?
+    fi
 }
 
 # This function can be used to access a tokenized list of words
@@ -288,7 +304,12 @@ _mvnd()
     local 
plugin_goals_formatter="formatter:format|formatter:help|formatter:validate"
 
     ## some plugin (like jboss-as) has '-' which is not allowed in shell var 
name, to use '_' then replace
-    local common_plugins=`compgen -v | grep "^plugin_goals_.*" | sed 
's/plugin_goals_//g' | tr '_' '-' | tr '\n' '|'`
+    local common_plugins
+    if [ "$__MVND_SHELL" = "zsh" ]; then
+        common_plugins=$(typeset + | grep "^plugin_goals_" | sed 
's/plugin_goals_//g' | tr '_' '-' | tr '\n' '|')
+    else
+        common_plugins=`compgen -v | grep "^plugin_goals_.*" | sed 
's/plugin_goals_//g' | tr '_' '-' | tr '\n' '|'`
+    fi
 
     local 
options="-Dmaven.test.skip=true|-DskipTests|-DskipITs|-Dtest|-Dit.test|-DfailIfNoTests|-Dmaven.surefire.debug|-DenableCiProfile|-Dpmd.skip=true|-Dcheckstyle.skip=true|-Dtycho.mode=maven|-Dmaven.javadoc.skip=true|-Dgwt.compiler.skip|-Dcobertura.skip=true|-Dfindbugs.skip=true||-DperformRelease=true|-Dgpg.skip=true|-DforkCount|${mvnd_properties}"
 
@@ -334,8 +355,14 @@ _mvnd()
         for plugin in $common_plugins; do
           if [[ ${cur} == ${plugin}:* ]]; then
             ## note that here is an 'unreplace', see the comment at 
common_plugins
-            var_name="plugin_goals_${plugin//-/_}"
-            COMPREPLY=( $(compgen -W "${!var_name}" -S ' ' -- ${cur}) )
+            local var_name="plugin_goals_${plugin//-/_}"
+            local var_value
+            if [ "$__MVND_SHELL" = "zsh" ]; then
+                var_value="${(P)var_name}"
+            else
+                var_value="${!var_name}"
+            fi
+            COMPREPLY=( $(compgen -W "${var_value}" -S ' ' -- ${cur}) )
           fi
         done
 
diff --git a/dist/src/main/distro/bin/mvnd-bash-completion.bash 
b/dist/src/main/distro/bin/mvnd-bash-completion.bash
index 692534a0..570adddb 100755
--- a/dist/src/main/distro/bin/mvnd-bash-completion.bash
+++ b/dist/src/main/distro/bin/mvnd-bash-completion.bash
@@ -17,10 +17,26 @@
 # Adapted from 
https://github.com/juven/maven-bash-completion/blob/master/bash_completion.bash 
by Juven Xu and others
 # under Apache License Version 2.0
 
+# Detect shell type and set up zsh compatibility if needed
+if [ -n "$ZSH_VERSION" ]; then
+    __MVND_SHELL="zsh"
+    # Load bashcompinit for bash-style completions in zsh
+    autoload -Uz bashcompinit 2>/dev/null && bashcompinit
+    # Define COMP_WORDBREAKS if not set (bash sets this automatically)
+    [[ -z "$COMP_WORDBREAKS" ]] && COMP_WORDBREAKS=$' \t\n"\'><=;|&(:'
+else
+    __MVND_SHELL="bash"
+fi
+
 function_exists()
 {
-    declare -F $1 > /dev/null
-    return $?
+    if [ "$__MVND_SHELL" = "zsh" ]; then
+        typeset -f $1 > /dev/null 2>&1
+        return $?
+    else
+        declare -F $1 > /dev/null
+        return $?
+    fi
 }
 
 # This function can be used to access a tokenized list of words
@@ -288,7 +304,12 @@ _mvnd()
     local 
plugin_goals_formatter="formatter:format|formatter:help|formatter:validate"
 
     ## some plugin (like jboss-as) has '-' which is not allowed in shell var 
name, to use '_' then replace
-    local common_plugins=`compgen -v | grep "^plugin_goals_.*" | sed 
's/plugin_goals_//g' | tr '_' '-' | tr '\n' '|'`
+    local common_plugins
+    if [ "$__MVND_SHELL" = "zsh" ]; then
+        common_plugins=$(typeset + | grep "^plugin_goals_" | sed 
's/plugin_goals_//g' | tr '_' '-' | tr '\n' '|')
+    else
+        common_plugins=`compgen -v | grep "^plugin_goals_.*" | sed 
's/plugin_goals_//g' | tr '_' '-' | tr '\n' '|'`
+    fi
 
     local 
options="-Dmaven.test.skip=true|-DskipTests|-DskipITs|-Dtest|-Dit.test|-DfailIfNoTests|-Dmaven.surefire.debug|-DenableCiProfile|-Dpmd.skip=true|-Dcheckstyle.skip=true|-Dtycho.mode=maven|-Dmaven.javadoc.skip=true|-Dgwt.compiler.skip|-Dcobertura.skip=true|-Dfindbugs.skip=true||-DperformRelease=true|-Dgpg.skip=true|-DforkCount|${mvnd_properties}"
 
@@ -334,8 +355,14 @@ _mvnd()
         for plugin in $common_plugins; do
           if [[ ${cur} == ${plugin}:* ]]; then
             ## note that here is an 'unreplace', see the comment at 
common_plugins
-            var_name="plugin_goals_${plugin//-/_}"
-            COMPREPLY=( $(compgen -W "${!var_name}" -S ' ' -- ${cur}) )
+            local var_name="plugin_goals_${plugin//-/_}"
+            local var_value
+            if [ "$__MVND_SHELL" = "zsh" ]; then
+                var_value="${(P)var_name}"
+            else
+                var_value="${!var_name}"
+            fi
+            COMPREPLY=( $(compgen -W "${var_value}" -S ' ' -- ${cur}) )
           fi
         done
 

Reply via email to