Merge branch 'jx/clean-interactive'

* jx/clean-interactive:
  git-clean: implement partial matching for selection
  Documentation/git-clean: fix description for range
This commit is contained in:
Junio C Hamano 2013-08-01 11:52:37 -07:00
commit c2980866b7
3 changed files with 91 additions and 31 deletions

View File

@ -111,7 +111,7 @@ select by numbers::
'>>' like this, you can make more than one selection, concatenated '>>' like this, you can make more than one selection, concatenated
with whitespace or comma. Also you can say ranges. E.g. "2-5 7,9" with whitespace or comma. Also you can say ranges. E.g. "2-5 7,9"
to choose 2,3,4,5,7,9 from the list. If the second number in a to choose 2,3,4,5,7,9 from the list. If the second number in a
range is omitted, all remaining patches are taken. E.g. "7-" to range is omitted, all remaining items are selected. E.g. "7-" to
choose 7,8,9 from the list. You can say '*' to choose everything. choose 7,8,9 from the list. You can say '*' to choose everything.
Also when you are satisfied with the filtered result, press ENTER Also when you are satisfied with the filtered result, press ENTER
(empty) back to the main menu. (empty) back to the main menu.

View File

@ -365,6 +365,56 @@ static void print_highlight_menu_stuff(struct menu_stuff *stuff, int **chosen)
string_list_clear(&menu_list, 0); 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). * Parse user input, and return choice(s) for menu (menu_stuff).
* *
@ -392,8 +442,6 @@ static int parse_choice(struct menu_stuff *menu_stuff,
int **chosen) int **chosen)
{ {
struct strbuf **choice_list, **ptr; struct strbuf **choice_list, **ptr;
struct menu_item *menu_item;
struct string_list_item *string_list_item;
int nr = 0; int nr = 0;
int i; int i;
@ -457,32 +505,8 @@ static int parse_choice(struct menu_stuff *menu_stuff,
bottom = 1; bottom = 1;
top = menu_stuff->nr; top = menu_stuff->nr;
} else { } else {
switch (menu_stuff->type) { bottom = find_unique((*ptr)->buf, menu_stuff);
default: top = bottom;
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;
}
} }
if (top <= 0 || bottom <= 0 || top > menu_stuff->nr || bottom > top || if (top <= 0 || bottom <= 0 || top > menu_stuff->nr || bottom > top ||

View File

@ -17,7 +17,7 @@ test_expect_success 'setup' '
' '
test_expect_success 'git clean -i (clean)' ' test_expect_success 'git clean -i (c: clean hotkey)' '
mkdir -p build docs && mkdir -p build docs &&
touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \
@ -38,12 +38,33 @@ test_expect_success 'git clean -i (clean)' '
' '
test_expect_success 'git clean -i (cl: clean prefix)' '
mkdir -p build docs &&
touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \
docs/manual.txt obj.o build/lib.so &&
echo cl | git clean -i &&
test -f Makefile &&
test -f README &&
test -f src/part1.c &&
test -f src/part2.c &&
test ! -f a.out &&
test -f docs/manual.txt &&
test ! -f src/part3.c &&
test ! -f src/part3.h &&
test ! -f src/part4.c &&
test ! -f src/part4.h &&
test -f obj.o &&
test -f build/lib.so
'
test_expect_success 'git clean -i (quit)' ' test_expect_success 'git clean -i (quit)' '
mkdir -p build docs && mkdir -p build docs &&
touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \
docs/manual.txt obj.o build/lib.so && docs/manual.txt obj.o build/lib.so &&
echo q | git clean -i && echo quit | git clean -i &&
test -f Makefile && test -f Makefile &&
test -f README && test -f README &&
test -f src/part1.c && test -f src/part1.c &&
@ -256,6 +277,21 @@ test_expect_success 'git clean -id (select - number 3)' '
' '
test_expect_success 'git clean -id (select - filenames)' '
mkdir -p build docs &&
touch a.out foo.txt bar.txt baz.txt &&
(echo s; echo a.out fo ba bar; echo; echo c) | \
git clean -id &&
test -f Makefile &&
test ! -f a.out &&
test ! -f foo.txt &&
test ! -f bar.txt &&
test -f baz.txt &&
rm baz.txt
'
test_expect_success 'git clean -id (select - range)' ' test_expect_success 'git clean -id (select - range)' '
mkdir -p build docs && mkdir -p build docs &&