@@ -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 ));
0 commit comments