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

Autocompletion bug for subcommands in zsh #178

Closed
remkop opened this issue Aug 28, 2017 · 7 comments
Closed

Autocompletion bug for subcommands in zsh #178

remkop opened this issue Aug 28, 2017 · 7 comments
Milestone

Comments

@remkop
Copy link
Owner

remkop commented Aug 28, 2017

on ZSH, the hierarchy test command always shows the top-level completions, even after a subcommand was selected.

Expected:

$ hierarchy sub2
-d           --directory  --num2       subsub1      subsub2

Actual:

$ hierarchy sub2
-h         --help     sub1       sub2       -V         --version
@remkop remkop added this to the 1.1.0 milestone Aug 28, 2017
@remkop
Copy link
Owner Author

remkop commented Aug 28, 2017

Tracked it down to a problem in the ArrContains function. The following code works in both bash and zsh:

function ArrContains() {
  local lArr1 lArr2
  declare -A tmp
  eval lArr1=("\"\${$1[@]}\"")
  eval lArr2=("\"\${$2[@]}\"")
  for i in "${lArr1[@]}";{ [ -n "$i" ] && ((++tmp[$i]));}
  for i in "${lArr2[@]}";{ [ -n "$i" ] && [ -z "${tmp[$i]}" ] && return 1;}
  return 0
}

@remkop
Copy link
Owner Author

remkop commented Aug 28, 2017

Index: src/main/java/picocli/AutoComplete.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/main/java/picocli/AutoComplete.java	(revision )
+++ src/main/java/picocli/AutoComplete.java	(revision )
@@ -249,8 +249,8 @@
             "  declare -A tmp\n" +
             "  eval lArr1=(\"\\\"\\${$1[@]}\\\"\")\n" +
             "  eval lArr2=(\"\\\"\\${$2[@]}\\\"\")\n" +
-            "  for i in \"${lArr1[@]}\";{ [ -n \"$i\" ] && ((++tmp['$i']));}\n" +
-            "  for i in \"${lArr2[@]}\";{ [ -z \"${tmp[$i]}\" ] && return 1;}\n" +
+            "  for i in \"${lArr1[@]}\";{ [ -n \"$i\" ] && ((++tmp[$i]));}\n" +
+            "  for i in \"${lArr2[@]}\";{ [ -n \"$i\" ] && [ -z \"${tmp[$i]}\" ] && return 1;}\n" +
             "  return 0\n" +
             "}\n" +
             "\n";

@remkop remkop modified the milestones: 1.0.1, 1.1.0 Aug 28, 2017
@remkop remkop closed this as completed in 79e57dd Aug 28, 2017
@Fadelis
Copy link

Fadelis commented Apr 25, 2018

Hello,

I'm having the same issue in bash.
When creating autocompletion script I'm passing the top level command with subcommands added via annotations. The generated script seems to have subcommands options in it, but when subcommand is typed only the top level suggestions are shown via tab.

@remkop
Copy link
Owner Author

remkop commented Apr 25, 2018

Can you provide a small program that demonstrates the issue so I can try to reproduce it?

@remkop remkop reopened this Apr 25, 2018
@Fadelis
Copy link

Fadelis commented Apr 25, 2018

So when trying to contain the issue to sample project, at first I could not replicate it. Then I saw that my subcommand have a separator between words and that was the culprit. Don't know if it is fixable, but I'll post the testcase anyway.

TestCase.java

@Command(
    name = "rcmd",
    mixinStandardHelpOptions = true,
    subcommands = {TestCase.Sub1Command.class, TestCase.Sub2Command.class}
)
public class TestCase {

  public static void main(String... args) {
    CommandLine command = new CommandLine(new TestCase());
    command.parseWithHandler(new RunAll(), args);
  }

  @Command(name = "sub-1", mixinStandardHelpOptions = true)
  public static class Sub1Command implements Runnable{

    @Option(names = "option1")
    int option1;

    @Option(names = "flag1")
    boolean flag1;

    public void run() {
      System.out.println(String.format("option1=%d, flag1=%s", option1, flag1));
    }
  }

  @Command(name = "sub-2", mixinStandardHelpOptions = true)
  public static class Sub2Command implements Runnable{

    @Option(names = "option2")
    int option2;

    @Option(names = "flag2")
    boolean flag2;

    public void run() {
      System.out.println(String.format("option2=%d, flag2=%s", option2, flag2));
    }
  }
}

Bash script for autocompletion

#!/usr/bin/env bash
PICOCLI_JAR=picocli-3.0.0-beta-2.jar
MAIN_DIR=src/main/java/
MAIN_CLASS=TestCase

alias rcmd='java -cp $PICOCLI_JAR;$MAIN_CLASS $MAIN_CLASS'
echo "created alias rcmd"

javac -cp $PICOCLI_JAR $MAIN_DIR/$MAIN_CLASS.java
java -cp "$PICOCLI_JAR:$MAIN_DIR" picocli.AutoComplete $MAIN_CLASS -f
. rcmd_completion
echo "created autocompletion"

EDIT:
It it is solvable if I update the rcmd_completion script with:

CMDS0=(sub1) --> CMDS0=(sub-1)
CMDS1=(sub2) --> CMDS1=(sub-2)

@remkop
Copy link
Owner Author

remkop commented Apr 25, 2018

Aha! Thank you for figuring that out. This is certainly fixable.

The problem is the AutoComplete.bashify method: it drops “invalid” characters and the current implementation only considers letters, digits and the underscore character ‘_’ as valid. At the very least the hyphen character should also not be discarded. (Need to check what other characters are “valid” bash identifier characters.)

Would you mind opening a separate ticket for this?

@remkop
Copy link
Owner Author

remkop commented Apr 27, 2018

Closing this ticket: following up on supporting hyphens in subcommands in #371.

@remkop remkop closed this as completed Apr 27, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants