IngoMeyer441 / simple-term-menu

A Python package which creates simple interactive menus on the command line.
MIT License
505 stars 44 forks source link

Feature request: multi-select #17

Closed dbrrt closed 3 years ago

dbrrt commented 3 years ago

Not sure if that's something that was ever considered, but I think it'd be great to have the ability to select multiple indexes rather than just one, in some cases.

For instance, imagine you want to walk-through a folder and select multiple files, you would select an index with SPACE BAR, and pressing enter will return an array of indexes, corresponding to the desired files.

API:

TerminalMenu(["entry 1", "entry 2", "entry 3"], multiple=True)
IngoMeyer441 commented 3 years ago

Thanks for your feature request. It's true, a multi-select feature was never considered during development and probably needs many code changes but it is for sure a useful feature. I try to make all changes also available to the standalone CLI version of simple-term-menu. The standalone program returns the selected menu index as exit code. Any ideas how multiple indices could be returned?

dbrrt commented 3 years ago

@IngoMeyer441 To be honest, I need more understanding on the current design of this library.

IngoMeyer441 commented 3 years ago

I think the standalone program could write multiple indices to stdout. We need a --stdout parameter for this first. A list of indices could then be used in a $() shell statement to capture the list and save it to a shell variable.

IngoMeyer441 commented 3 years ago

The latest develop branch adds a multi-select mode:

#!/usr/bin/env python3

from simple_term_menu import TerminalMenu

def main():
    terminal_menu = TerminalMenu(["dog", "cat", "mouse", "squirrel"], multi_select=True)
    menu_entry_indices = terminal_menu.show()
    print(menu_entry_indices)
    print(terminal_menu.chosen_menu_entries)

if __name__ == "__main__":
    main()

You can install the development version directly from GitHub to test the changes for your workflow:

pip install git+https://github.com/IngoMeyer441/simple-term-menu@develop
IngoMeyer441 commented 3 years ago

As you suggested, the show method returns a Tuple of ints in multi-select mode and a single int otherwise. The terminal program prints multiple indices to stdout and separates them with ,.

dbrrt commented 3 years ago

Thanks @IngoMeyer441 for your reactivity and having implemented it. Will try this feature ASAP.

IngoMeyer441 commented 3 years ago

@Seluj78 Perhaps, a multi-select feature is also interesting for you.

Seluj78 commented 3 years ago

It definitely might, thanks ! I have the repo as watched for all new issues but thanks for the mention 😁 I'll check it out when I have time

dbrrt commented 3 years ago

@IngoMeyer441 Just found some time to test this new feature, it works just fine on my side, exactly as I would have expected it. To be finicky, I'd add an helper text, to select more than one record, press space on the desired records, then press return like for the search so it could be understandable for the end user.

Screenshot 2021-03-06 at 04 10 44 Screenshot 2021-03-06 at 04 08 22

Also, using another character such as * would help colorblind users to differentiate the pointer from the already selected records (in addition to the label overlay). Another idea long term would be to replace > with [ ] and selected elements would be then [x] in a multi-select context.

Great job! I'm looking forward to integrate this into my CLIs.

IngoMeyer441 commented 3 years ago

Thanks for testing and your feedback! :slightly_smiling_face: Using another default cursor for color blind people is a good point. I also added an option to display a multi-selection hint in the status bar (show_multi_select_hint):

multi_select

The status bar feature was requested in #16.

dbrrt commented 3 years ago

Thanks @IngoMeyer441 !!

IngoMeyer441 commented 3 years ago

The new feature is included in the v0.11.0 release.

I plan to publish a v1.0.0 release in the next minutes which has some few breaking changes, so you may want to stick with the v0.11.0 release (these changes are documented in the README file).

Feel free to reopen if the multi-select feature still lacks some important feature or you find bugs.

YAMLcase commented 3 years ago

Just to add on to this idea:

Another idea long term would be to replace > with [ ] and selected elements would be then [x] in a multi-select context.

I find it difficult to know if the current item is selected since the cursor doesn't change... maybe introducing a third cursor character to indicate both conditions. I also like the idea of not using the same character > for the cursor as with single-select to immediately queue the user they can multi-select w/out reading the bottom line. something like this perhaps (I think some more thought can go into my character choices):

selects zero and one, then moves down the list:

+ zero
+ one
  two
- three
  four
  five

moves back up to one:

+ zero
* one
  two
  three
  four
  five
IngoMeyer441 commented 3 years ago

Definitely a good idea to improve the cursor in multi-selection mode. We could also use two columns like this:

  [x] zero
  [x] one
  [ ] two
> [ ] three
  [ ] four
  [ ] five
YAMLcase commented 3 years ago

oh I like the idea of two columns. using existing look-n-feel:

 * zero
>* one
   two
   three
   four
   five
IngoMeyer441 commented 3 years ago

The latest develop adds a second column for multi-selection. The default multi_select cursor is now [*] (ncurses style). Brackets and the rest of the cursor can be styled independently from each other. Looks like this:

multi_select

IngoMeyer441 commented 3 years ago

The cursor can also be set to only * to get the old look-and-feel, but with two columns.

YAMLcase commented 3 years ago

Just tried it out and I love it. Thanks for the quick change!

IngoMeyer441 commented 3 years ago

I am going to publish a new release next week that will include all the changes of the last days. 😄

IngoMeyer441 commented 3 years ago

The changes are now in the latest v1.2.0 release.