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 ;
@@ -337,12 +357,29 @@ static void populate_wi_changes(struct strbuf *buf,
337
357
strbuf_addstr (buf , no_changes );
338
358
}
339
359
360
+ /* filters out prefixes which have special meaning to list_and_choose() */
361
+ static int is_valid_prefix (const char * prefix , size_t prefix_len )
362
+ {
363
+ return prefix_len && prefix &&
364
+ /*
365
+ * We expect `prefix` to be NUL terminated, therefore this
366
+ * `strcspn()` call is okay, even if it might do much more
367
+ * work than strictly necessary.
368
+ */
369
+ strcspn (prefix , " \t\r\n," ) >= prefix_len && /* separators */
370
+ * prefix != '-' && /* deselection */
371
+ !isdigit (* prefix ) && /* selection */
372
+ (prefix_len != 1 ||
373
+ (* prefix != '*' && /* "all" wildcard */
374
+ * prefix != '?' )); /* prompt help */
375
+ }
376
+
340
377
struct print_file_item_data {
341
378
const char * modified_fmt ;
342
379
struct strbuf buf , index , worktree ;
343
380
};
344
381
345
- static void print_file_item (int i , struct item * item ,
382
+ static void print_file_item (int i , struct prefix_item * item ,
346
383
void * print_file_item_data )
347
384
{
348
385
struct file_item * c = (struct file_item * )item ;
@@ -369,20 +406,26 @@ static int run_status(struct add_i_state *s, const struct pathspec *ps,
369
406
return -1 ;
370
407
371
408
if (files -> nr )
372
- list ((struct item * * )files -> file , files -> nr , s , opts );
409
+ list ((struct prefix_item * * )files -> file , files -> nr , s , opts );
373
410
putchar ('\n' );
374
411
375
412
return 0 ;
376
413
}
377
414
378
- static void print_command_item (int i , struct item * item ,
415
+ static void print_command_item (int i , struct prefix_item * item ,
379
416
void * print_command_item_data )
380
417
{
381
- printf (" %2d: %s" , i + 1 , item -> name );
418
+ if (!item -> prefix_length ||
419
+ !is_valid_prefix (item -> name , item -> prefix_length ))
420
+ printf (" %2d: %s" , i + 1 , item -> name );
421
+ else
422
+ printf (" %3d: [%.*s]%s" , i + 1 ,
423
+ (int )item -> prefix_length , item -> name ,
424
+ item -> name + item -> prefix_length );
382
425
}
383
426
384
427
struct command_item {
385
- struct item item ;
428
+ struct prefix_item item ;
386
429
int (* command )(struct add_i_state * s , const struct pathspec * ps ,
387
430
struct file_list * files , struct list_options * opts );
388
431
};
@@ -424,7 +467,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
424
467
res = -1 ;
425
468
426
469
for (;;) {
427
- i = list_and_choose ((struct item * * )commands ,
470
+ i = list_and_choose ((struct prefix_item * * )commands ,
428
471
ARRAY_SIZE (commands ), & s , & main_loop_opts );
429
472
if (i == LIST_AND_CHOOSE_QUIT ) {
430
473
printf (_ ("Bye.\n" ));
0 commit comments