diff --git a/.github/workflows/dejagnu.yml b/.github/workflows/dejagnu.yml
new file mode 100644
index 000000000..d71fafef9
--- /dev/null
+++ b/.github/workflows/dejagnu.yml
@@ -0,0 +1,27 @@
+name: DejaGnu Tests
+
+on: [ push, pull_request ]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install Fish shell and DejaGnu
+ run: |
+ sudo apt-add-repository -y ppa:fish-shell/release-3
+ sudo apt-get update
+ sudo apt-get install -y fish dejagnu tcllib
+ - name: Check versions
+ run: |
+ fish --version
+ runtest --version
+ - name: Checkout
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v2
+ - name: Run DejaGnu fish tests
+ run: |
+ cd src/test/dejagnu.fishtests
+ ./runCompletion
+ - name: Run DejaGnu bash tests
+ run: |
+ cd src/test/dejagnu.tests
+ ./runCompletion
diff --git a/.gitignore b/.gitignore
index 5f9ca8177..a7537ce7f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,5 +15,7 @@ picocli.iml
/src/test/dejagnu.tests/testrun.log
/src/test/dejagnu.tests/testrun.sum
/src/test/dejagnu.tests/tmp/
+/src/test/dejagnu.fishtests/log/completion.sum
+/src/test/dejagnu.fishtests/log/completion.log
/picocli-tests-java567/gradle/wrapper/dists/**/*.lck
/picocli-tests-java567/gradle/wrapper/dists/**/*.ok
diff --git a/docs/man/index.html b/docs/man/index.html
index 6442f11de..08f67de29 100644
--- a/docs/man/index.html
+++ b/docs/man/index.html
@@ -435,81 +435,81 @@
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
-
-
-
+
+
+
diff --git a/docs/zh/picocli-2.0-do-more-with-less.html b/docs/zh/picocli-2.0-do-more-with-less.html
index ed5d027fd..bc4735113 100644
--- a/docs/zh/picocli-2.0-do-more-with-less.html
+++ b/docs/zh/picocli-2.0-do-more-with-less.html
@@ -525,81 +525,81 @@
.CodeRay .change .change{color:#66f}
.CodeRay .head .head{color:#f4f}
-
-
-
+
+
+
diff --git a/docs/zh/picocli-2.0-groovy-scripts-on-steroids.html b/docs/zh/picocli-2.0-groovy-scripts-on-steroids.html
index 03efa574f..d0170a7df 100644
--- a/docs/zh/picocli-2.0-groovy-scripts-on-steroids.html
+++ b/docs/zh/picocli-2.0-groovy-scripts-on-steroids.html
@@ -525,81 +525,81 @@
.CodeRay .change .change{color:#66f}
.CodeRay .head .head{color:#f4f}
-
-
-
+
+
+
diff --git a/src/main/java/picocli/AutoComplete.java b/src/main/java/picocli/AutoComplete.java
index 17e9580d1..16bf3fa13 100644
--- a/src/main/java/picocli/AutoComplete.java
+++ b/src/main/java/picocli/AutoComplete.java
@@ -534,6 +534,129 @@ public static String bash(String scriptName, CommandLine commandLine) {
return result.toString();
}
+
+ public static String fish(String scriptName, CommandLine commandLine) {
+ if (scriptName == null) { throw new NullPointerException("scriptName"); }
+ if (commandLine == null) { throw new NullPointerException("commandLine"); }
+ List hierarchy = createHierarchy(scriptName, commandLine);
+ StringBuilder result = new StringBuilder();
+
+ String parentFunction = "";
+ List currentLevel = new ArrayList();
+ List currentLevelCommands = new ArrayList();
+
+ CommandDescriptor rootDescriptor = null;
+ for (CommandDescriptor descriptor : hierarchy) {
+ if (descriptor.parentFunctionName.equals("")) {
+ rootDescriptor = descriptor;
+ parentFunction = descriptor.functionName;
+ continue;
+ }
+ if (!descriptor.parentFunctionName.equals(parentFunction)) {
+ processLevel(scriptName, result, currentLevel, currentLevelCommands, parentFunction, rootDescriptor);
+ rootDescriptor = null;
+
+ currentLevel.clear();
+ currentLevelCommands.clear();
+ parentFunction = descriptor.parentFunctionName;
+ }
+
+ currentLevel.add(descriptor);
+ currentLevelCommands.add(descriptor.commandName);
+ }
+ processLevel(scriptName, result, currentLevel, currentLevelCommands, parentFunction, rootDescriptor);
+
+
+ return result.toString();
+ }
+
+ private static void processLevel(String scriptName, StringBuilder result, List currentLevel,
+ List currentLevelCommands, String levelName,
+ CommandDescriptor rootDescriptor) {
+ if (levelName.equals("")) {
+ levelName = "root";
+ }
+
+ // fish doesn't like dashes in variable names
+ levelName = levelName.replaceAll("-", "_");
+
+ result.append("\n# ").append(levelName).append(" completion\n");
+ result.append("set -l ").append(levelName);
+ if (!currentLevelCommands.isEmpty()) {
+ result.append(" ").append(join(" ", currentLevelCommands));
+ }
+ result.append("\n");
+ if (rootDescriptor != null) {
+ String condition = " --condition \"not __fish_seen_subcommand_from $" + levelName + "\"";
+ for (OptionSpec optionSpec : rootDescriptor.commandLine.getCommandSpec().options()) {
+ completeFishOption(scriptName, optionSpec, condition, result);
+ }
+ }
+ for (CommandDescriptor commandDescriptor : currentLevel) {
+
+ result.append("complete -c ").append(scriptName);
+ result.append(" --no-files"); // do not show files
+ result.append(" --condition \"not __fish_seen_subcommand_from $").append(levelName).append("\"");
+ if (!commandDescriptor.parentWithoutTopLevelCommand.equals("")) {
+ result.append(" --condition '__fish_seen_subcommand_from ").append(
+ commandDescriptor.parentWithoutTopLevelCommand).append("'");
+ }
+
+ result.append(" --arguments ").append(commandDescriptor.commandName);
+
+ String[] descriptions = commandDescriptor.commandLine.getCommandSpec().usageMessage().description();
+ String description = descriptions.length > 0 ? descriptions[0] : "";
+ result.append(" -d '").append(sanitizeFishDescription(description)).append("'\n");
+
+ String condition = getFishCondition(commandDescriptor);
+ for (OptionSpec optionSpec : commandDescriptor.commandLine.getCommandSpec().options()) {
+ completeFishOption(scriptName, optionSpec, condition, result);
+ }
+ }
+ }
+
+ private static String getFishCondition(CommandDescriptor commandDescriptor) {
+ StringBuilder condition = new StringBuilder();
+ condition.append(" --condition \"__fish_seen_subcommand_from ").append(commandDescriptor.commandName).append("\"");
+ if (!commandDescriptor.parentWithoutTopLevelCommand.equals("")) {
+ condition.append(" --condition '__fish_seen_subcommand_from ").append(
+ commandDescriptor.parentWithoutTopLevelCommand).append("'");
+ }
+ return condition.toString();
+ }
+
+ private static void completeFishOption(String scriptName, OptionSpec optionSpec, String conditions, StringBuilder result) {
+ result.append("complete -c ").append(scriptName);
+ result.append(conditions);
+ result.append(" --long-option ").append(optionSpec.longestName().replace("--", ""));
+
+ if (!optionSpec.shortestName().equals(optionSpec.longestName())) {
+ result.append(" --short-option ").append(optionSpec.shortestName().replace("-", ""));
+ }
+
+ if (optionSpec.completionCandidates() != null) {
+ result.append(" --no-files --arguments '").append(join(" ", extract(optionSpec.completionCandidates()))).append("' ");
+ }
+
+ String optionDescription = sanitizeFishDescription(optionSpec.description().length > 0 ? optionSpec.description()[0] : "");
+ result.append(" -d '").append(optionDescription).append("'\n");
+ }
+
+ private static String sanitizeFishDescription(String description) {
+ return description.replace("'", "\\'");
+ }
+
+ private static String join(String delimeter, List list) {
+ StringBuilder result = new StringBuilder();
+ for (int i = 0; i < list.size(); i++) {
+ if (i > 0) {
+ result.append(delimeter);
+ }
+ result.append(list.get(i));
+ }
+ return result.toString();
+ }
+
private static List createHierarchy(String scriptName, CommandLine commandLine) {
List result = new ArrayList();
result.add(new CommandDescriptor("_picocli_" + scriptName, "", "", scriptName, commandLine));
diff --git a/src/test/dejagnu.fishtests/README.adoc b/src/test/dejagnu.fishtests/README.adoc
new file mode 100644
index 000000000..28caddea8
--- /dev/null
+++ b/src/test/dejagnu.fishtests/README.adoc
@@ -0,0 +1,4 @@
+Run
+```
+runtest --outdir log --tool completion
+```
\ No newline at end of file
diff --git a/src/test/dejagnu.fishtests/completion/basicExample.exp b/src/test/dejagnu.fishtests/completion/basicExample.exp
new file mode 100644
index 000000000..87b8ad714
--- /dev/null
+++ b/src/test/dejagnu.fishtests/completion/basicExample.exp
@@ -0,0 +1,23 @@
+set timeout 1
+
+# Setup completion and fake command
+send "source ../resources/basic.fish\r"
+expect -re "(.+>)"
+
+send "function basicExample; echo 'do'; end\r"
+expect -re "(.+>)"
+
+set cmd "basicExample -"
+set test "Tab should show options for '$cmd'"
+set candidates "-t -u --timeout --timeUnit --timeUnit="
+run_completion_test $cmd $test $candidates
+
+set cmd "basicExample --"
+set test "Tab should show options for '$cmd'"
+set candidates "--timeout --timeUnit --timeUnit="
+run_completion_test $cmd $test $candidates
+
+set cmd "basicExample --timeUnit="
+set test "Tab should show time unit enum values for '$cmd'"
+set candidates ".*timeUnit=DAYS.*timeUnit=MICROSECONDS.*timeUnit=MINUTES.*timeUnit=SECONDS.*timeUnit=HOURS.*timeUnit=MILLISECONDS.*timeUnit=NANOSECONDS.*"
+run_completion_test $cmd $test $candidates
diff --git a/src/test/dejagnu.fishtests/completion/picocompletion-demo.exp b/src/test/dejagnu.fishtests/completion/picocompletion-demo.exp
new file mode 100644
index 000000000..b7fe60c88
--- /dev/null
+++ b/src/test/dejagnu.fishtests/completion/picocompletion-demo.exp
@@ -0,0 +1,24 @@
+exp_internal 1
+set timeout 1
+
+# Setup completion and fake command
+send "source ../resources/picocompletion-demo_completion.fish\r"
+expect -re "(.+>)"
+
+send "function picocompletion-demo; echo 'do'; end\r"
+expect -re "(.+>)"
+
+set cmd "picocompletion-demo "
+set test "Tab should show sub1 and sub2 for '${cmd}'"
+# for some reason, bash completion doesn't show sub1-alias and sub2-alias
+set candidates "sub1.*sub1-alias.*sub2.*sub2-alias.*"
+run_completion_test $cmd $test $candidates
+
+# now we show files in this test
+# set cmd "picocompletion-demo sub1 "
+# set test "Tab should not show completions for '${cmd}'"
+
+set cmd "picocompletion-demo sub1 -"
+set test "Tab should show sub1 options for '${cmd}'"
+set candidates "--candidates.*--candidates=.*--num.*--str.*"
+run_completion_test $cmd $test $candidates
diff --git a/src/test/dejagnu.fishtests/lib/completion.exp b/src/test/dejagnu.fishtests/lib/completion.exp
new file mode 100644
index 000000000..073f24663
--- /dev/null
+++ b/src/test/dejagnu.fishtests/lib/completion.exp
@@ -0,0 +1,8 @@
+exp_spawn fish --no-config
+expect -re "(.+>)"
+
+# Set terminal size to my notebook's resolution
+send "stty rows 53 cols 190\r"
+expect -re "(.+>)"
+
+source $::srcdir/lib/library.exp
diff --git a/src/test/dejagnu.fishtests/lib/library.exp b/src/test/dejagnu.fishtests/lib/library.exp
new file mode 100644
index 000000000..e2fb3f33f
--- /dev/null
+++ b/src/test/dejagnu.fishtests/lib/library.exp
@@ -0,0 +1,11 @@
+proc run_completion_test {cmd test candidates} {
+ exp_internal 1
+ send "${cmd}\t"
+ expect {
+ -re "(\n${candidates}\u001b)" { pass $test }
+ timeout { fail $test }
+ }
+ exp_internal 0
+ send "\x03"
+ expect ">"
+}
diff --git a/src/test/dejagnu.fishtests/runCompletion b/src/test/dejagnu.fishtests/runCompletion
new file mode 100755
index 000000000..a475f1f18
--- /dev/null
+++ b/src/test/dejagnu.fishtests/runCompletion
@@ -0,0 +1,3 @@
+#!/bin/bash
+mkdir -p log
+runtest --outdir log --tool completion
diff --git a/src/test/dejagnu.tests/runCompletion b/src/test/dejagnu.tests/runCompletion
old mode 100644
new mode 100755
diff --git a/src/test/java/picocli/AutoCompleteDejaGnuTest.java b/src/test/java/picocli/AutoCompleteDejaGnuTest.java
index 0c2363c98..280baeb50 100644
--- a/src/test/java/picocli/AutoCompleteDejaGnuTest.java
+++ b/src/test/java/picocli/AutoCompleteDejaGnuTest.java
@@ -67,11 +67,19 @@ public void tryRunDejaGnuCompletionTests() throws Exception {
// ignores test if dejagnu not installed
org.junit.Assume.assumeTrue("dejagnu must be installed to run this test", isDejaGnuInstalled());
- runDejaGnuCompletionTests();
+ runDejaGnuCompletionTests("src/test/dejagnu.tests");
}
- private void runDejaGnuCompletionTests() throws Exception {
- final File testDir = new File("src/test/dejagnu.tests");
+ @Test
+ public void tryRunFishDejaGnuCompletionTests() throws Exception {
+ // ignores test if dejagnu not installed
+ org.junit.Assume.assumeTrue("dejagnu must be installed to run this test", isDejaGnuInstalled());
+ runDejaGnuCompletionTests("src/test/dejagnu.fishtests");
+ }
+
+
+ private void runDejaGnuCompletionTests(String pathname) throws Exception {
+ final File testDir = new File(pathname);
assertTrue(testDir.getAbsolutePath() + " should exist", testDir.exists());
File runCompletionScript = new File(testDir, "runCompletion");
assertTrue(runCompletionScript.getAbsolutePath() + " should exist", runCompletionScript.exists());
diff --git a/src/test/java/picocli/AutoCompleteTest.java b/src/test/java/picocli/AutoCompleteTest.java
index 0397eaf7a..4f5bb39a3 100644
--- a/src/test/java/picocli/AutoCompleteTest.java
+++ b/src/test/java/picocli/AutoCompleteTest.java
@@ -91,6 +91,14 @@ public void basic() throws Exception {
assertEquals(expected, script);
}
+ @Test
+ public void basicFish() throws Exception {
+ String script = AutoComplete.fish("basicExample", new CommandLine(new BasicExample()));
+ System.out.println(script);
+ String expected = loadTextFromClasspath("/basic.fish");
+ assertEquals(expected, script);
+ }
+
public static class TopLevel {
@Option(names = {"-V", "--version"}, help = true) boolean versionRequested;
@Option(names = {"-h", "--help"}, help = true) boolean helpRequested;
@@ -173,19 +181,33 @@ public static class Sub2Child3 {
// }
@Test
public void nestedSubcommands() throws Exception {
- CommandLine hierarchy = new CommandLine(new TopLevel())
- .addSubcommand("sub1", new Sub1())
- .addSubcommand("sub2", new CommandLine(new Sub2())
- .addSubcommand("subsub1", new Sub2Child1())
- .addSubcommand("subsub2", new Sub2Child2())
- .addSubcommand("subsub3", new Sub2Child3())
- );
+ CommandLine hierarchy = getNestedSubcommandsCommandLine();
String script = AutoComplete.bash("picocompletion-demo", hierarchy);
String expected = format(loadTextFromClasspath("/picocompletion-demo_completion.bash"),
CommandLine.VERSION, concat("\" \"", TimeUnit.values()));
assertEquals(expected, script);
}
+ @Test
+ public void nestedSubcommandsFish() throws Exception {
+ CommandLine hierarchy = getNestedSubcommandsCommandLine();
+ String script = AutoComplete.fish("picocompletion-demo", hierarchy);
+ System.out.println(script);
+ String expected = loadTextFromClasspath("/picocompletion-demo_completion.fish");
+ assertEquals(expected, script);
+ }
+
+ private static CommandLine getNestedSubcommandsCommandLine() {
+ CommandLine hierarchy = new CommandLine(new TopLevel())
+ .addSubcommand("sub1", new Sub1())
+ .addSubcommand("sub2", new CommandLine(new Sub2())
+ .addSubcommand("subsub1", new Sub2Child1())
+ .addSubcommand("subsub2", new Sub2Child2())
+ .addSubcommand("subsub3", new Sub2Child3())
+ );
+ return hierarchy;
+ }
+
@Test
public void helpCommand() {
CommandLine hierarchy = new CommandLine(new AutoCompleteTest.TopLevel())
diff --git a/src/test/resources/basic.fish b/src/test/resources/basic.fish
new file mode 100644
index 000000000..2ac7ce4ef
--- /dev/null
+++ b/src/test/resources/basic.fish
@@ -0,0 +1,5 @@
+
+# _picocli_basicExample completion
+set -l _picocli_basicExample
+complete -c basicExample --condition "not __fish_seen_subcommand_from $_picocli_basicExample" --long-option timeUnit --short-option u --no-files --arguments 'NANOSECONDS MICROSECONDS MILLISECONDS SECONDS MINUTES HOURS DAYS' -d ''
+complete -c basicExample --condition "not __fish_seen_subcommand_from $_picocli_basicExample" --long-option timeout --short-option t -d ''
diff --git a/src/test/resources/picocompletion-demo_completion.fish b/src/test/resources/picocompletion-demo_completion.fish
new file mode 100644
index 000000000..feccfd286
--- /dev/null
+++ b/src/test/resources/picocompletion-demo_completion.fish
@@ -0,0 +1,49 @@
+
+# _picocli_picocompletion_demo completion
+set -l _picocli_picocompletion_demo sub1 sub1-alias sub2 sub2-alias
+complete -c picocompletion-demo --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo" --long-option version --short-option V -d ''
+complete -c picocompletion-demo --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo" --long-option help --short-option h -d ''
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo" --arguments sub1 -d 'First level subcommand 1'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub1" --long-option num -d 'a number'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub1" --long-option str -d 'a String'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub1" --long-option candidates --no-files --arguments 'aaa bbb ccc' -d 'with candidates'
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo" --arguments sub1-alias -d 'First level subcommand 1'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub1-alias" --long-option num -d 'a number'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub1-alias" --long-option str -d 'a String'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub1-alias" --long-option candidates --no-files --arguments 'aaa bbb ccc' -d 'with candidates'
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo" --arguments sub2 -d 'First level subcommand 2'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub2" --long-option num2 -d 'another number'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub2" --long-option directory --short-option d -d 'a directory'
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo" --arguments sub2-alias -d 'First level subcommand 2'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub2-alias" --long-option num2 -d 'another number'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub2-alias" --long-option directory --short-option d -d 'a directory'
+
+# _picocli_picocompletion_demo_sub2 completion
+set -l _picocli_picocompletion_demo_sub2 subsub1 sub2child1-alias subsub2 sub2child2-alias subsub3 sub2child3-alias
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo_sub2" --condition '__fish_seen_subcommand_from sub2' --arguments subsub1 -d 'Second level sub-subcommand 1'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from subsub1" --condition '__fish_seen_subcommand_from sub2' --long-option host --short-option h -d 'a host'
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo_sub2" --condition '__fish_seen_subcommand_from sub2' --arguments sub2child1-alias -d 'Second level sub-subcommand 1'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub2child1-alias" --condition '__fish_seen_subcommand_from sub2' --long-option host --short-option h -d 'a host'
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo_sub2" --condition '__fish_seen_subcommand_from sub2' --arguments subsub2 -d 'Second level sub-subcommand 2'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from subsub2" --condition '__fish_seen_subcommand_from sub2' --long-option timeUnit --short-option u --no-files --arguments 'NANOSECONDS MICROSECONDS MILLISECONDS SECONDS MINUTES HOURS DAYS' -d ''
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from subsub2" --condition '__fish_seen_subcommand_from sub2' --long-option timeout --short-option t -d ''
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo_sub2" --condition '__fish_seen_subcommand_from sub2' --arguments sub2child2-alias -d 'Second level sub-subcommand 2'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub2child2-alias" --condition '__fish_seen_subcommand_from sub2' --long-option timeUnit --short-option u --no-files --arguments 'NANOSECONDS MICROSECONDS MILLISECONDS SECONDS MINUTES HOURS DAYS' -d ''
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub2child2-alias" --condition '__fish_seen_subcommand_from sub2' --long-option timeout --short-option t -d ''
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo_sub2" --condition '__fish_seen_subcommand_from sub2' --arguments subsub3 -d 'Second level sub-subcommand 3'
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo_sub2" --condition '__fish_seen_subcommand_from sub2' --arguments sub2child3-alias -d 'Second level sub-subcommand 3'
+
+# _picocli_picocompletion_demo_sub2alias completion
+set -l _picocli_picocompletion_demo_sub2alias subsub1 sub2child1-alias subsub2 sub2child2-alias subsub3 sub2child3-alias
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo_sub2alias" --condition '__fish_seen_subcommand_from sub2-alias' --arguments subsub1 -d 'Second level sub-subcommand 1'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from subsub1" --condition '__fish_seen_subcommand_from sub2-alias' --long-option host --short-option h -d 'a host'
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo_sub2alias" --condition '__fish_seen_subcommand_from sub2-alias' --arguments sub2child1-alias -d 'Second level sub-subcommand 1'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub2child1-alias" --condition '__fish_seen_subcommand_from sub2-alias' --long-option host --short-option h -d 'a host'
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo_sub2alias" --condition '__fish_seen_subcommand_from sub2-alias' --arguments subsub2 -d 'Second level sub-subcommand 2'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from subsub2" --condition '__fish_seen_subcommand_from sub2-alias' --long-option timeUnit --short-option u --no-files --arguments 'NANOSECONDS MICROSECONDS MILLISECONDS SECONDS MINUTES HOURS DAYS' -d ''
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from subsub2" --condition '__fish_seen_subcommand_from sub2-alias' --long-option timeout --short-option t -d ''
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo_sub2alias" --condition '__fish_seen_subcommand_from sub2-alias' --arguments sub2child2-alias -d 'Second level sub-subcommand 2'
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub2child2-alias" --condition '__fish_seen_subcommand_from sub2-alias' --long-option timeUnit --short-option u --no-files --arguments 'NANOSECONDS MICROSECONDS MILLISECONDS SECONDS MINUTES HOURS DAYS' -d ''
+complete -c picocompletion-demo --condition "__fish_seen_subcommand_from sub2child2-alias" --condition '__fish_seen_subcommand_from sub2-alias' --long-option timeout --short-option t -d ''
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo_sub2alias" --condition '__fish_seen_subcommand_from sub2-alias' --arguments subsub3 -d 'Second level sub-subcommand 3'
+complete -c picocompletion-demo --no-files --condition "not __fish_seen_subcommand_from $_picocli_picocompletion_demo_sub2alias" --condition '__fish_seen_subcommand_from sub2-alias' --arguments sub2child3-alias -d 'Second level sub-subcommand 3'