string_list_clear(&menu_list, 0);
}
+static int find_unique(const char *choice, struct menu_stuff *menu_stuff)
+{
+ struct menu_item *menu_item;
+ struct string_list_item *string_list_item;
+ int i, len, found = 0;
+
+ len = strlen(choice);
+ switch (menu_stuff->type) {
+ default:
+ die("Bad type of menu_stuff when parse choice");
+ case MENU_STUFF_TYPE_MENU_ITEM:
+
+ menu_item = (struct menu_item *)menu_stuff->stuff;
+ for (i = 0; i < menu_stuff->nr; i++, menu_item++) {
+ if (len == 1 && *choice == menu_item->hotkey) {
+ found = i + 1;
+ break;
+ }
+ if (!strncasecmp(choice, menu_item->title, len)) {
+ if (found) {
+ if (len == 1) {
+ /* continue for hotkey matching */
+ found = -1;
+ } else {
+ found = 0;
+ break;
+ }
+ } else {
+ found = i + 1;
+ }
+ }
+ }
+ break;
+ case MENU_STUFF_TYPE_STRING_LIST:
+ string_list_item = ((struct string_list *)menu_stuff->stuff)->items;
+ for (i = 0; i < menu_stuff->nr; i++, string_list_item++) {
+ if (!strncasecmp(choice, string_list_item->string, len)) {
+ if (found) {
+ found = 0;
+ break;
+ }
+ found = i + 1;
+ }
+ }
+ break;
+ }
+ return found;
+}
+
+
/*
* Parse user input, and return choice(s) for menu (menu_stuff).
*
int **chosen)
{
struct strbuf **choice_list, **ptr;
- struct menu_item *menu_item;
- struct string_list_item *string_list_item;
int nr = 0;
int i;
bottom = 1;
top = menu_stuff->nr;
} else {
- switch (menu_stuff->type) {
- default:
- die("Bad type of menu_stuff when parse choice");
- case MENU_STUFF_TYPE_MENU_ITEM:
- menu_item = (struct menu_item *)menu_stuff->stuff;
- for (i = 0; i < menu_stuff->nr; i++, menu_item++) {
- if (((*ptr)->len == 1 &&
- *(*ptr)->buf == menu_item->hotkey) ||
- !strcasecmp((*ptr)->buf, menu_item->title)) {
- bottom = i + 1;
- top = bottom;
- break;
- }
- }
- break;
- case MENU_STUFF_TYPE_STRING_LIST:
- string_list_item = ((struct string_list *)menu_stuff->stuff)->items;
- for (i = 0; i < menu_stuff->nr; i++, string_list_item++) {
- if (!strcasecmp((*ptr)->buf, string_list_item->string)) {
- bottom = i + 1;
- top = bottom;
- break;
- }
- }
- break;
- }
+ bottom = find_unique((*ptr)->buf, menu_stuff);
+ top = bottom;
}
if (top <= 0 || bottom <= 0 || top > menu_stuff->nr || bottom > top ||
return 0;
}
+static int ask_each_cmd(void)
+{
+ struct strbuf confirm = STRBUF_INIT;
+ struct strbuf buf = STRBUF_INIT;
+ struct string_list_item *item;
+ const char *qname;
+ int changed = 0, eof = 0;
+
+ for_each_string_list_item(item, &del_list) {
+ /* Ctrl-D should stop removing files */
+ if (!eof) {
+ qname = quote_path_relative(item->string, NULL, &buf);
+ printf(_("remove %s? "), qname);
+ if (strbuf_getline(&confirm, stdin, '\n') != EOF) {
+ strbuf_trim(&confirm);
+ } else {
+ putchar('\n');
+ eof = 1;
+ }
+ }
+ if (!confirm.len || strncasecmp(confirm.buf, "yes", confirm.len)) {
+ *item->string = '\0';
+ changed++;
+ }
+ }
+
+ if (changed)
+ string_list_remove_empty_items(&del_list, 0);
+
+ strbuf_release(&buf);
+ strbuf_release(&confirm);
+ return MENU_RETURN_NO_LOOP;
+}
+
static int quit_cmd(void)
{
string_list_clear(&del_list, 0);
"clean - start cleaning\n"
"filter by pattern - exclude items from deletion\n"
"select by numbers - select items to be deleted by numbers\n"
+ "ask each - confirm each deletion (like \"rm -i\")\n"
"quit - stop cleaning\n"
"help - this screen\n"
"? - help for prompt selection"
{'c', "clean", 0, clean_cmd},
{'f', "filter by pattern", 0, filter_by_patterns_cmd},
{'s', "select by numbers", 0, select_by_numbers_cmd},
+ {'a', "ask each", 0, ask_each_cmd},
{'q', "quit", 0, quit_cmd},
{'h', "help", 0, help_cmd},
};
struct dir_entry *ent = dir.entries[i];
int len, pos;
int matches = 0;
- struct cache_entry *ce;
+ const struct cache_entry *ce;
struct stat st;
const char *rel;