Skip to content

Commit 96c3ec2

Browse files
serg-vvolkov
authored andcommitted
picocli fish completion
1 parent 9c4e8a2 commit 96c3ec2

File tree

2 files changed

+72
-33
lines changed

2 files changed

+72
-33
lines changed

src/main/java/picocli/AutoComplete.java

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -305,17 +305,6 @@ private static class CommandDescriptor {
305305
this.commandName = commandName;
306306
this.commandLine = commandLine;
307307
}
308-
309-
@Override
310-
public String toString() {
311-
return "CommandDescriptor{" +
312-
"functionName='" + functionName + '\'' +
313-
", parentFunctionName='" + parentFunctionName + '\'' +
314-
", parentWithoutTopLevelCommand='" + parentWithoutTopLevelCommand + '\'' +
315-
", commandName='" + commandName + '\'' +
316-
", commandLine=" + commandLine +
317-
'}';
318-
}
319308
}
320309

321310
private static final String SCRIPT_HEADER = "" +
@@ -551,18 +540,84 @@ public static String fish(String scriptName, CommandLine commandLine) {
551540
if (commandLine == null) { throw new NullPointerException("commandLine"); }
552541
List<CommandDescriptor> hierarchy = createHierarchy(scriptName, commandLine);
553542
//print hierarchy
543+
StringBuilder result = new StringBuilder();
544+
//result.append("complete --command ").append(scriptName).append(" --no-files").append("\n");
545+
546+
String parentFunction = "";
547+
List<CommandDescriptor> currentLevel = new ArrayList<>();
548+
List<String> currentLevelCommands = new ArrayList<>();
554549
for (CommandDescriptor descriptor : hierarchy) {
555-
System.out.println(descriptor.functionName + " " + descriptor.commandName);
556-
}
550+
if (descriptor.parentFunctionName.equals("")) {
551+
continue;
552+
}
553+
if (!descriptor.parentFunctionName.equals(parentFunction)) {
554+
if (!currentLevelCommands.isEmpty()) {
555+
processLevel(scriptName, result, currentLevel, currentLevelCommands, parentFunction);
557556

558-
StringBuilder result = new StringBuilder();
559-
result.append("Hello from fish!").append("\n");
560-
for (CommandDescriptor commandDescriptor : hierarchy) {
561-
result.append(commandDescriptor.toString()).append("\n");
557+
currentLevel.clear();
558+
currentLevelCommands.clear();
559+
}
560+
parentFunction = descriptor.parentFunctionName;
561+
}
562+
563+
currentLevel.add(descriptor);
564+
currentLevelCommands.add(descriptor.commandName);
565+
}
566+
if (!currentLevelCommands.isEmpty()) {
567+
processLevel(scriptName, result, currentLevel, currentLevelCommands, parentFunction);
562568
}
569+
570+
563571
return result.toString();
564572
}
565573

574+
private static void processLevel(String scriptName, StringBuilder result, List<CommandDescriptor> currentLevel,
575+
List<String> currentLevelCommands, String levelName) {
576+
result.append("\n# ").append(levelName).append(" completion \n");
577+
result.append("set -l ").append(levelName).append(" ").append(String.join(" ", currentLevelCommands)).append(
578+
"\n");
579+
for (CommandDescriptor commandDescriptor : currentLevel) {
580+
String[] descriptions = commandDescriptor.commandLine.getCommandSpec().usageMessage().description();
581+
String description = descriptions.length > 0 ? descriptions[0] : "";
582+
result.append("complete -c ").append(scriptName);
583+
result.append(" -f"); // do not show files
584+
result.append(" -n \"not __fish_seen_subcommand_from $").append(levelName).append("\"");
585+
if (!commandDescriptor.parentWithoutTopLevelCommand.equals("")) {
586+
result.append(" -n '__fish_seen_subcommand_from ").append(
587+
commandDescriptor.parentWithoutTopLevelCommand).append("'");
588+
}
589+
result.append(" -a ").append(commandDescriptor.commandName).append(" -d '").append(description).append("'\n");
590+
591+
for (OptionSpec optionSpec : commandDescriptor.commandLine.getCommandSpec().options()) {
592+
result.append("complete -c ").append(scriptName);
593+
result.append(" -n \"__fish_seen_subcommand_from ").append(commandDescriptor.commandName).append("\"");
594+
if (!commandDescriptor.parentWithoutTopLevelCommand.equals("")) {
595+
result.append(" -n '__fish_seen_subcommand_from ").append(
596+
commandDescriptor.parentWithoutTopLevelCommand).append("'");
597+
}
598+
result.append(" -l ").append(optionSpec.longestName().replace("--", ""));
599+
String optionDescription = sanitizeDescription(optionSpec.description().length > 0 ? optionSpec.description()[0] : "");
600+
result.append(" -d '").append(optionDescription).append("'\n");
601+
602+
if (!optionSpec.shortestName().equals(optionSpec.longestName())) {
603+
result.append("complete -c ").append(scriptName);
604+
result.append(" -n \"__fish_seen_subcommand_from ").append(commandDescriptor.commandName).append("\"");
605+
if (!commandDescriptor.parentWithoutTopLevelCommand.equals("")) {
606+
result.append(" -n '__fish_seen_subcommand_from ").append(
607+
commandDescriptor.parentWithoutTopLevelCommand).append("'");
608+
}
609+
result.append(" -s ").append(optionSpec.shortestName().replace("-", ""));
610+
result.append(" -d '").append(optionDescription).append("'\n");
611+
}
612+
}
613+
}
614+
615+
}
616+
617+
private static String sanitizeDescription(String description) {
618+
return description.replace("'", "\\'");
619+
}
620+
566621
private static List<CommandDescriptor> createHierarchy(String scriptName, CommandLine commandLine) {
567622
List<CommandDescriptor> result = new ArrayList<CommandDescriptor>();
568623
result.add(new CommandDescriptor("_picocli_" + scriptName, "", "", scriptName, commandLine));

src/test/java/picocli/AutoCompleteTest.java

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2117,20 +2117,4 @@ public void testIssue1388_AliasesCommand() throws FileNotFoundException {
21172117
existingScript.delete();
21182118
}
21192119
}
2120-
2121-
@Test
2122-
public void testFish() {
2123-
String expected = String.format("hello from fish%n");
2124-
2125-
assertEquals(
2126-
expected,
2127-
AutoComplete.fish("myapp", new CommandLine(new Issue1352CommandWithResourceBundle()))
2128-
);
2129-
2130-
assertEquals(
2131-
expected,
2132-
AutoComplete.fish("myapp", new CommandLine(new Issue1352ParentCommand()))
2133-
);
2134-
2135-
}
21362120
}

0 commit comments

Comments
 (0)