pcapriotti / optparse-applicative

Applicative option parser
BSD 3-Clause "New" or "Revised" License
907 stars 114 forks source link

Showing help on empty with inline subcommands #450

Open moll opened 2 years ago

moll commented 2 years ago

Hey again!

Hope your spring is going swell.

Do you have some tips on how to achieve showing help-on-empty when subcommands and subparsers are involved? That is, given something that contains the following:

cmd = Opt.subparser $
  Opt.command "foo" $ Opt.info fooCommands $
  Opt.progDesc "Foo commands."

fooCommands = Opt.subparser $
  Opt.command "bar" $ Opt.info (pure 'x') $
  Opt.progDesc "Go to bar."

..I'm trying to achieve that invoking ./program foo would print out the help with its subcommands (bar) along with local and global options. This with Opt.prefBacktrack = Opt.SubparserInline.

Right now I'm seeing ./program showing the top level commands (foo), however ./program foo erring with:

Usage: program foo COMMAND
Missing: COMMAND

Thanks in advance!

HuwCampbell commented 2 years ago

The prefs mod showHelpOnEmpty works with subparsers as well as the top level.

*Options.Applicative Opt> main = customExecParser (prefs (showHelpOnEmpty <> subparserInline)) (info cmd idm)
*Options.Applicative Opt> :main foo
Missing: COMMAND

Usage: <interactive> foo COMMAND

  Foo commands.
moll commented 2 years ago

Hey. Thanks for the quick response! Apologies. I classified the problem inadequately, I now realize. You're right. Help-on-empty for the subcommand does indeed show the usage line referencing the subcommand and any global options. What it does not seem to show are the subcommands themselves.

That is, at the top level there's a grouping listing all next level commands:

Usage: program COMMAND

Available commands:
  foo Foo commands.

Now I was expecting and trying to get the subparser to behave similarly — show available commands next level down. In the example we're playing with here, that'd be:

Missing: COMMAND

Usage: program foo COMMAND
  Foo commands.

Available commands:
  bar Go to bar.

Thanks!

HuwCampbell commented 2 years ago

Ahh I see now.

When subparser inline is on, the subcommand is just included as a component of the parent parser. The parent parser isn't at its start though, so the showHelpOnEmpty case isn't being activated.

Interesting little edge case there.

This should be fixable by included a bit more information in the result of searchArg and stepParser.

HuwCampbell commented 2 years ago

I have a fix and tests. The code is too ugly to push for now, but I'll see if I can get something acceptable next weekend.

moll commented 2 years ago

Great. Thank you!

moll commented 3 months ago

Hey again! Am I mistaken if I say the fix you did back in 2022 has never made it to master? Thanks!