spectreconsole / spectre.console

A .NET library that makes it easier to create beautiful console applications.
https://spectreconsole.net
MIT License
9.43k stars 498 forks source link

Tab completion for CLI #267

Closed phil-scott-78 closed 10 months ago

phil-scott-78 commented 3 years ago

I was going to toy around with adding powershell or bash tab completion for my app, but it occurred to me that it might be possible (and maybe even easier) to bake this in. I'd

The way some tools work is they provide something like a completion command that accepts the list of currently typed arguments (e.g. if I was typing git checkout sp[tab] it would run git completion checkout sp and the application would supply the tab information.

My Saturday night plan for investigation the feasibility would be for simple things like enums and bools to automatically return the valid values. But for strings it would work like ParameterValidationAttribute where you could have

public abstract CompletionResult Complete(ICommandParameterInfo info, object? value);

And you'd mark up your settings appropriately. You'd want services to be injected though. TBH I'm not sure if the validation code allows that as is.

Reading

OskarKlintrot commented 3 years ago

Great idea! Just a heads up, the PS-script for tab completion for .NET CLI is taking the whole command, i.e. "dotnet ad" and not just ad. So git checkout sp[tab] would be git completion "git checkout sp" (one string, not an array of args). I noticed that while making my own trying to follow Hanselman's blog post. I have no clue if there is such a thing as a best practice for this but that is the way they have done it for the dotnet cli.

patriksvensson commented 3 years ago

@phil-scott-78 @OskarKlintrot Another option would be to add a generator to Spectre.Console.Cli, that generates the shell binding s for an application, such as myapp.exe cli generate powershell. I know that Clap for Rust does this and it seems to work fairly well: https://github.com/clap-rs/clap/blob/master/clap_generate/src/generators/shells/powershell.rs

OskarKlintrot commented 3 years ago

Stupid question but does it generate the equivalent of the ps-script you add to $profile or dotnet complete?

One thing to keep in mind is that it can be useful to be able to generate suggestions dynamically. For example, our CLI is for working with our repos so the suggestions of <repo> in my-tool clone <repo> must be dynamic.

patriksvensson commented 3 years ago

@OskarKlintrot Ah, no, it wouldn't. I see no problem with adding a dynamic generator as you suggested above 👍🏻

Jawz84 commented 2 years ago

@patriksvensson @phil-scott-78 I think this would be so cool to have, that I am interested in starting a PR for this. I'd probably need some help though. From reading the code I have a reasonably clear idea where to start.I'm thinking of adding to the existing hidden default cli commands:

Given an app myapp with a command lion: myapp cli complete 'myapp l' should result in lion

(That's basically the unit test i've written)

Need some more time to come up with actual implementation. Would that be OK with you?

phil-scott-78 commented 2 years ago

Absolutely. Lets use this to brainstorm some scenarios and go from there. My little guy is stealing a ton of my time so extended coding sessions are a rarity so being able to assist would be great

I'll try and come up with a few more test ideas to drive this tonight

Jawz84 commented 2 years ago

That sounds great! I have a little time today, so I'll see if I can come up with a little poc implementation to get my feet wet. I'll fork and push a branch to my github so you can have a look.

Jawz84 commented 2 years ago

Follow my progress here: https://github.com/spectreconsole/spectre.console/compare/main...Jawz84:adds_267_completer?expand=1 Opened the PR as suggested, so we can have continuous discussion.

patriksvensson commented 2 years ago

@Jawz84 Great! Feel free to open a PR before finishing it so that we can have a continuous discussion.

FrankRay78 commented 10 months ago

Superceded by https://github.com/spectreconsole/spectre.console/issues/1243.