spectre.console icon indicating copy to clipboard operation
spectre.console copied to clipboard

MultiSelect defaults for MultiSelectionPrompt

Open RichiCoder1 opened this issue 2 years ago • 9 comments

Is your feature request related to a problem? Please describe. Previously it was possible to select multiple items in MultiSelectionPrompt, allowing for multiple defaults. Working around this by just selecting each in a loop.

Describe the solution you'd like A replacement extension method to allow selecting multiple defaults again.

Describe alternatives you've considered Just selecting manually, it's working now.

Additional context These previously existed, but was removed with the MultiSelect refactor.,

RichiCoder1 avatar Jul 19 '21 16:07 RichiCoder1

@RichiCoder1 Not sure if I misunderstand something, but I just tried it out and it's still working. Could you share some code that reproduces this?

image

patriksvensson avatar Jul 19 '21 17:07 patriksvensson

Ahh! I should clarify, setting defaults by calling the extension method Select on MultiSelectionPrompt, which used to accept an Enumerable of indices to select. This was a convient way to set multiple default selections before presentation to the user.

RichiCoder1 avatar Jul 19 '21 17:07 RichiCoder1

Removed here: https://github.com/spectreconsole/spectre.console/commit/865552c3f2046282519b85e543ed516142f7785a#diff-0e766947d13f6d9db4fd4cee1aa7845d9c776f4009124784ceb62e41b0939248L150

RichiCoder1 avatar Jul 19 '21 17:07 RichiCoder1

@RichiCoder1 Ah, yes. We obsoleted those a while back and recently removed them since they don't make much sense anymore after making the list hierarchical. There are, however, new methods for selecting items.

I'll write up an example once I'm at a computer.

patriksvensson avatar Jul 19 '21 17:07 patriksvensson

I guess I have a weird case where hierarchical doesn't make sense, but I still want a number of items selected. I'm making it work fine using Select in a loop though, so I'm not blocked at all. Can close this out though if it's an edge case request.

RichiCoder1 avatar Jul 19 '21 18:07 RichiCoder1

Sorry to jump on this, but I also stumbled a bit when I tried to implement selecting multiple items. (Mostly because of me, though...)

@RichiCoder1 Are you saying what you are currently missing is something like this: https://github.com/spectreconsole/spectre.console/commit/393b2b54e5e320f7e311014bdb2582bb922a1206#diff-a84d869307529eb26cb15b7f6566d9f31950d7ec0eacc2130fa9afc3a2ade7c4R115

nils-a avatar Jul 19 '21 21:07 nils-a

@RichiCoder1 I don't think we should close this out. I don't think you're alone in wanting to select items in an easy way (@nils-a's comment proves this).

Question is, how can we make this easier to discover in the API? Can we add some extension method, such as AddSelectedItem/AddSelectedItems? Would something like that help?

patriksvensson avatar Jul 19 '21 22:07 patriksvensson

Ooo, that'd work too. Or maybe an overload to AddChoices takes defaults as a second arg? Either would be good.

RichiCoder1 avatar Jul 19 '21 23:07 RichiCoder1

Well, my problem was that I was "looking" at the current develop branch (i.e. 0.41.preview-something) trying to figure out selection while I referenced the 0.40.0 version.

But I think it's not as easy as AddSelectedItem - at least not for a hierarchical MultiSelectionPrompt. Only the first level of descendants are IMultiSelectionItem which support Select().

So, while one can do

var prompt = new MultiSelectionPrompt<string>();
prompt.AddChoices("one", c => s.Select())

one can not do

var prompt = new MultiSelectionPrompt<string>();
prompt.AddChoices("one", c => c.AddChild("one.one").Select())

or something like that.

AddChoices has a bunch of overloads and I would hesitate do duplicate each of them with an AddChoicesSelected variant.

I think it would make more sense to ensure every overload has the option to pass a Action<IMultiSelectionItem<T>> configurator and that the ISelectionItem<T> can also be Select()-ed like IMultiSelectionItem<T>

That way one should be able to do something like:

var prompt = new MultiSelectionPrompt<string>();
prompt.AddChoices(new[]{ "one", "two", "three" }, c => s.Select())
var prompt = new MultiSelectionPrompt<string>();
prompt.AddChoices(new[]{ "one", "two", "three" }, root => root.AddChild(string.format("{0}.one", root)).Select())

or even

var prompt = new MultiSelectionPrompt<string>();
prompt.AddChoices(new[]{ "one", "two", "three" }, root => root.AddChildren(string.format("{0}.one", root), string.format("{0}.two", root)), child => child.Select())

(That last one is me, dreaming, really...)

nils-a avatar Jul 19 '21 23:07 nils-a