Document for interactive git-clean says: You also could say `c` or
`clean` above as long as the choice is unique. But it's not true,
because only hotkey `c` and full match (`clean`) could work.
Implement partial matching via find_unique function to make the
document right.
Signed-off-by: Jiang Xin worldhello@gmail.com
---
builtin/clean.c | 80
t/t7301-clean-interactive.sh | 40 --
2 files changed, 90 insertions(+), 30 deletions(-)
diff --git a/builtin/clean.c b/builtin/clean.c
index dba8387..3c85e15 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -365,6 +365,56 @@ static void print_highlight_menu_stuff(struct menu_stuff
*stuff, int **chosen)
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).
*
@@ -392,8 +442,6 @@ static int parse_choice(struct menu_stuff *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;
@@ -457,32 +505,8 @@ static int parse_choice(struct menu_stuff *menu_stuff,
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 =