clikt icon indicating copy to clipboard operation
clikt copied to clipboard

Custom order for OptionGroup

Open joffrey-bion opened this issue 4 months ago • 4 comments

Is there any way to order option groups below the main options?

I have some advanced debugging options that are less important than the regular options. I placed them in a group so they appear separately in the help. Now they are shown first, but I'd like them to be last. How can I change this?

I declared the group last in the command properties, so I expected this to work like for the options order, but it didn't:

Usage: amper [<options>] <command> [<args>]...

Debugging options:

  Advanced options to debug Amper itself

  --async-profiler                            Profile Amper with Async Profiler
  --coroutines-debug / --no-coroutines-debug  Enable coroutines debug probes. This allows to dump the running coroutines in case of deadlock.

Options:
  -v, --version                            Show the version and exit
  --root=<path>                            Amper project root
  --log-level=(debug|info|warn|error|off)  Console logging level (default: INFO)
  --shared-caches-root=<path>              Path to the cache directory shared between all Amper projects (default: C:\Users\Joffrey.Bion\AppData\Local\JetBrains\Amper)
  --build-output=<path>                    Root directory for build outputs. By default, this is the build directory under the project root.
  -h, --help                               Show this message and exit

Commands:
  build                Compile and link all code in the project
  clean                Remove the project's build output and caches
  clean-shared-caches  Remove the Amper caches that are shared between projects
  generate-completion  Generate a tab-completion script for the Amper command for the given shell (bash, zsh, or fish)
  init                 Initialize a new Amper project based on a template
  package              Package the project artifacts for distribution
  publish              Publish modules to a repository
  run                  Run your application
  show                 Show information about some aspect the project (modules, tasks, effective settings...). See help for details.
  task                 Run a task and its dependencies from the task graph
  test                 Run tests in the project
  tool                 Run a tool
  update               Update Amper to the latest version

joffrey-bion avatar Oct 05 '25 16:10 joffrey-bion

You can override renderOptions in your help formatter to order them how you'd like.

ajalt avatar Oct 06 '25 16:10 ajalt

Thanks, I'll check that!

joffrey-bion avatar Oct 06 '25 18:10 joffrey-bion

So indeed it seems possible to get any order by overriding renderOptions, but it means I'll have to duplicate the entire original code just to change the sorting part.

I wanted to call super.renderOptions() to reuse the original code and just sort the sections after the fact, but then I have no access to the original group types or even names (the title is not the same, because it is already styled and might contain ANSI codes).

joffrey-bion avatar Oct 07 '25 21:10 joffrey-bion

What do you think about respecting the order of the delegates from the original commands (the same way they are respected to sort the options within a group)?

Here is a suggestion:

  • order explicit option groups the same way as the properties/delegates in the command
  • to place the group of "ungrouped options" with respect to the other option groups, use the position of the first ungrouped option among the delegates

This is a simple way to do it, and it guarantees that placing all ungrouped options after or before an option group will behave as expected. If some command author mixes ungrouped options and option groups, we at least have a deterministic way to go about it, and anyway it probably means they don't care about order.

Example 1: ungrouped options after all groups

val group1 by OptionGroup1()
val group2 by OptionGroup2()
val opt1 by option("--option1")
val opt2 by option("--option2")
Group 1
  ...
Group 2
  ...
Options
  --option1
  --option2

Example 2: ungrouped options before all groups

val opt1 by option("--option1")
val opt2 by option("--option2")
val group1 by OptionGroup1()
val group2 by OptionGroup2()
Options
  --option1
  --option2
Group 1
  ...
Group 2
  ...

Example 3: ungrouped options between groups but together

val group1 by OptionGroup1()
val opt1 by option("--option1")
val opt2 by option("--option2")
val group2 by OptionGroup2()
Group 1
  ...
Options
  --option1
  --option2
Group 2
  ...

Example 4: ungrouped options mixed with groups

val group1 by OptionGroup1()
val opt1 by option("--option1")
val group2 by OptionGroup2()
val opt2 by option("--option2")
Group 1
  ...
Options
  --option1
  --option2
Group 2
  ...

This last example is kinda arbitrary, but the order of the delegates is weird anyway, so probably any order is fine for the author of such a command.

joffrey-bion avatar Oct 07 '25 21:10 joffrey-bion