git-clean: add select by numbers interactive action

Draw a multiple choice menu using `list_and_choose` to select items to be deleted by numbers. User can input: * 1,5-7 : select 1,5,6,7 items to be deleted * * : select all items to be deleted * -* : unselect all, nothing will be deleted * : (empty) finish selecting, and return back to main menu Signed-off-by: Jiang Xin <worldhello.net@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jiang Xin committed Jun 25, 2013 at 23:53 UTC c1f1d24aa5c72821096e2a31aaf4175329ca0260
1 file changed +39
builtin/clean.c
+39
@@ -680,6 +680,43 @@ static int filter_by_patterns_cmd(void)
680 return 0;
681 }
682
683 +static int select_by_numbers_cmd(void)
684 +{
685 + struct menu_opts menu_opts;
686 + struct menu_stuff menu_stuff;
687 + struct string_list_item *items;
688 + int *chosen;
689 + int i, j;
690 +
691 + menu_opts.header = NULL;
692 + menu_opts.prompt = N_("Select items to delete");
693 + menu_opts.flags = 0;
694 +
695 + menu_stuff.type = MENU_STUFF_TYPE_STRING_LIST;
696 + menu_stuff.stuff = &del_list;
697 + menu_stuff.nr = del_list.nr;
698 +
699 + chosen = list_and_choose(&menu_opts, &menu_stuff);
700 + items = del_list.items;
701 + for (i = 0, j = 0; i < del_list.nr; i++) {
702 + if (i < chosen[j]) {
703 + *(items[i].string) = '\0';
704 + } else if (i == chosen[j]) {
705 + /* delete selected item */
706 + j++;
707 + continue;
708 + } else {
709 + /* end of chosen (chosen[j] == EOF), won't delete */
710 + *(items[i].string) = '\0';
711 + }
712 + }
713 +
714 + string_list_remove_empty_items(&del_list, 0);
715 +
716 + free(chosen);
717 + return 0;
718 +}
719 +
720 static int quit_cmd(void)
721 {
722 string_list_clear(&del_list, 0);
@@ -693,6 +730,7 @@ static int help_cmd(void)
730 printf_ln(_(
731 "clean - start cleaning\n"
732 "filter by pattern - exclude items from deletion\n"
733 + "select by numbers - select items to be deleted by numbers\n"
734 "quit - stop cleaning\n"
735 "help - this screen\n"
736 "? - help for prompt selection"
@@ -709,6 +747,7 @@ static void interactive_main_loop(void)
747 struct menu_item menus[] = {
748 {'c', "clean", 0, clean_cmd},
749 {'f', "filter by pattern", 0, filter_by_patterns_cmd},
750 + {'s', "select by numbers", 0, select_by_numbers_cmd},
751 {'q', "quit", 0, quit_cmd},
752 {'h', "help", 0, help_cmd},
753 };