5
5
#include "diffcore.h"
6
6
#include "revision.h"
7
7
#include "refs.h"
8
+ #include "prefix-map.h"
8
9
9
10
struct add_i_state {
10
11
struct repository * r ;
@@ -46,18 +47,32 @@ static int init_add_i_state(struct repository *r, struct add_i_state *s)
46
47
return 0 ;
47
48
}
48
49
49
- struct item {
50
- const char * name ;
51
- };
50
+ static ssize_t find_unique (const char * string ,
51
+ struct prefix_item * * list , size_t nr )
52
+ {
53
+ ssize_t found = -1 , i ;
54
+
55
+ for (i = 0 ; i < nr ; i ++ ) {
56
+ struct prefix_item * item = list [i ];
57
+ if (!starts_with (item -> name , string ))
58
+ continue ;
59
+ if (found >= 0 )
60
+ return -1 ;
61
+ found = i ;
62
+ }
63
+
64
+ return found ;
65
+ }
52
66
53
67
struct list_options {
54
68
int columns ;
55
69
const char * header ;
56
- void (* print_item )(int i , struct item * item , void * print_item_data );
70
+ void (* print_item )(int i , struct prefix_item * item ,
71
+ void * print_item_data );
57
72
void * print_item_data ;
58
73
};
59
74
60
- static void list (struct item * * list , size_t nr ,
75
+ static void list (struct prefix_item * * list , size_t nr ,
61
76
struct add_i_state * s , struct list_options * opts )
62
77
{
63
78
int i , last_lf = 0 ;
@@ -100,13 +115,15 @@ struct list_and_choose_options {
100
115
* If an error occurred, returns `LIST_AND_CHOOSE_ERROR`. Upon EOF,
101
116
* `LIST_AND_CHOOSE_QUIT` is returned.
102
117
*/
103
- static ssize_t list_and_choose (struct item * * items , size_t nr ,
118
+ static ssize_t list_and_choose (struct prefix_item * * items , size_t nr ,
104
119
struct add_i_state * s ,
105
120
struct list_and_choose_options * opts )
106
121
{
107
122
struct strbuf input = STRBUF_INIT ;
108
123
ssize_t res = LIST_AND_CHOOSE_ERROR ;
109
124
125
+ find_unique_prefixes (items , nr , 1 , 4 );
126
+
110
127
for (;;) {
111
128
char * p , * endp ;
112
129
@@ -146,6 +163,9 @@ static ssize_t list_and_choose(struct item **items, size_t nr,
146
163
}
147
164
148
165
p [sep ] = '\0' ;
166
+ if (index < 0 )
167
+ index = find_unique (p , items , nr );
168
+
149
169
if (index < 0 || index >= nr )
150
170
printf (_ ("Huh (%s)?\n" ), p );
151
171
else {
@@ -171,7 +191,7 @@ struct adddel {
171
191
172
192
struct file_list {
173
193
struct file_item {
174
- struct item item ;
194
+ struct prefix_item item ;
175
195
struct adddel index , worktree ;
176
196
} * * file ;
177
197
size_t nr , alloc ;
@@ -338,12 +358,29 @@ static void populate_wi_changes(struct strbuf *buf,
338
358
strbuf_addstr (buf , no_changes );
339
359
}
340
360
361
+ /* filters out prefixes which have special meaning to list_and_choose() */
362
+ static int is_valid_prefix (const char * prefix , size_t prefix_len )
363
+ {
364
+ return prefix_len && prefix &&
365
+ /*
366
+ * We expect `prefix` to be NUL terminated, therefore this
367
+ * `strcspn()` call is okay, even if it might do much more
368
+ * work than strictly necessary.
369
+ */
370
+ strcspn (prefix , " \t\r\n," ) >= prefix_len && /* separators */
371
+ * prefix != '-' && /* deselection */
372
+ !isdigit (* prefix ) && /* selection */
373
+ (prefix_len != 1 ||
374
+ (* prefix != '*' && /* "all" wildcard */
375
+ * prefix != '?' )); /* prompt help */
376
+ }
377
+
341
378
struct print_file_item_data {
342
379
const char * modified_fmt ;
343
380
struct strbuf buf , index , worktree ;
344
381
};
345
382
346
- static void print_file_item (int i , struct item * item ,
383
+ static void print_file_item (int i , struct prefix_item * item ,
347
384
void * print_file_item_data )
348
385
{
349
386
struct file_item * c = (struct file_item * )item ;
@@ -370,20 +407,26 @@ static int run_status(struct add_i_state *s, const struct pathspec *ps,
370
407
return -1 ;
371
408
372
409
if (files -> nr )
373
- list ((struct item * * )files -> file , files -> nr , s , opts );
410
+ list ((struct prefix_item * * )files -> file , files -> nr , s , opts );
374
411
putchar ('\n' );
375
412
376
413
return 0 ;
377
414
}
378
415
379
- static void print_command_item (int i , struct item * item ,
416
+ static void print_command_item (int i , struct prefix_item * item ,
380
417
void * print_command_item_data )
381
418
{
382
- printf (" %2d: %s" , i + 1 , item -> name );
419
+ if (!item -> prefix_length ||
420
+ !is_valid_prefix (item -> name , item -> prefix_length ))
421
+ printf (" %2d: %s" , i + 1 , item -> name );
422
+ else
423
+ printf (" %3d: [%.*s]%s" , i + 1 ,
424
+ (int )item -> prefix_length , item -> name ,
425
+ item -> name + item -> prefix_length );
383
426
}
384
427
385
428
struct command_item {
386
- struct item item ;
429
+ struct prefix_item item ;
387
430
int (* command )(struct add_i_state * s , const struct pathspec * ps ,
388
431
struct file_list * files , struct list_options * opts );
389
432
};
@@ -425,7 +468,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
425
468
res = -1 ;
426
469
427
470
for (;;) {
428
- i = list_and_choose ((struct item * * )commands ,
471
+ i = list_and_choose ((struct prefix_item * * )commands ,
429
472
ARRAY_SIZE (commands ), & s , & main_loop_opts );
430
473
if (i == LIST_AND_CHOOSE_QUIT ) {
431
474
printf (_ ("Bye.\n" ));
0 commit comments