Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to remove a subcommand #4927

Open
2 tasks done
kvece opened this issue May 20, 2023 · 4 comments
Open
2 tasks done

Add ability to remove a subcommand #4927

kvece opened this issue May 20, 2023 · 4 comments
Labels
C-enhancement Category: Raise on the bar on expectations

Comments

@kvece
Copy link

kvece commented May 20, 2023

Please complete the following tasks

Clap Version

master

Describe your use case

Basically I am trying to make an interactive REPL

I decided to originally follow from the recipe provided in the cookbook, basically have a root command set with multicall and I all commands in the REPL are implemented as subcommands.

However, when the commands are the REPL are dynamic, I can add commands easily but removing commands that are no longer requires rebuilding the entire Command struct with the desired subcommand missing, which is rather tedious.

Describe the solution you'd like

I just took the mut_subcommand function, copied it, and modified it to a remove_subcommand function that has the same functionality except without the callback and without placing a subcommand back into self.subcommands

Alternatives, if applicable

The other option I considered was modifying the subcommand function that followed the builder pattern, but since I'm not sure why you would need to remove a command in a builder pattern, I thought it was easier to modify the struct rather than create a new one.

Additional Context

No response

@kvece kvece added the C-enhancement Category: Raise on the bar on expectations label May 20, 2023
@epage
Copy link
Member

epage commented May 21, 2023

Could you expand on the use case for why commands are being added and removed during the lifetime of the REPL?

@kvece
Copy link
Author

kvece commented May 21, 2023

Sure, picture an interactive CLI with a plugin system:

> load plugin
> # associated commands become available
> unload plugin
> # associated commands no longer available

An alternative design could be:

> use plugin
plugin> # opens a submenu with only the associated commands
plugin> back
> # associated commands no longer available

But this has the issue where switching back and forth between plugin commands is more tedious for the user (ideally user can load multiple plugins into namespace at once)

Another alternative would be to allow multiple at once:

> use plugin1
plugin1> # opens submenu command object with plugin1 commands added
plugin1> use plugin2
plugin1,plugin2> # opens another object with plugin2 added
plugin1,plugin2> unload plugin1    # now say plugin1 is no longer needed
plugin2> # now I have to start from the root Command and rebuild the object, current solution

@kvece
Copy link
Author

kvece commented May 21, 2023

Or reference similar functionality in popular python module here: https://cmd2.readthedocs.io/en/stable/features/modular_commands.html

@epage
Copy link
Member

epage commented May 21, 2023

This isn't the right approach with clap's design. clap expects everything to be added and then "builds". Once the build happens, changes shouldn't be made (I'd like to enforce this within the type system but haven't found a satisfactory design yet). Using this in a REPL to add / remove commands implies an existing instance is being reused. As an alternative, you could recreate your Command on each interaction which will let you add the currently active plugins though I don't know if the cost for that would be reasonable.

For cmd2, it looks like they have an ArgumentParsser per command and I suspect that would be the right way to model this within your application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-enhancement Category: Raise on the bar on expectations
Projects
None yet
Development

No branches or pull requests

2 participants