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 ;
@@ -94,13 +109,15 @@ struct list_and_choose_options {
94
109
/*
95
110
* Returns the selected index.
96
111
*/
97
- static ssize_t list_and_choose (struct item * * items , size_t nr ,
112
+ static ssize_t list_and_choose (struct prefix_item * * items , size_t nr ,
98
113
struct add_i_state * s ,
99
114
struct list_and_choose_options * opts )
100
115
{
101
116
struct strbuf input = STRBUF_INIT ;
102
117
ssize_t res = -1 ;
103
118
119
+ find_unique_prefixes (items , nr , 1 , 4 );
120
+
104
121
for (;;) {
105
122
char * p , * endp ;
106
123
@@ -140,6 +157,9 @@ static ssize_t list_and_choose(struct item **items, size_t nr,
140
157
}
141
158
142
159
p [sep ] = '\0' ;
160
+ if (index < 0 )
161
+ index = find_unique (p , items , nr );
162
+
143
163
if (index < 0 || index >= nr )
144
164
printf (_ ("Huh (%s)?\n" ), p );
145
165
else {
@@ -165,7 +185,7 @@ struct adddel {
165
185
166
186
struct file_list {
167
187
struct file_item {
168
- struct item item ;
188
+ struct prefix_item item ;
169
189
struct adddel index , worktree ;
170
190
} * * file ;
171
191
size_t nr , alloc ;
@@ -331,12 +351,29 @@ static void populate_wi_changes(struct strbuf *buf,
331
351
strbuf_addstr (buf , no_changes );
332
352
}
333
353
354
+ /* filters out prefixes which have special meaning to list_and_choose() */
355
+ static int is_valid_prefix (const char * prefix , size_t prefix_len )
356
+ {
357
+ return prefix_len && prefix &&
358
+ /*
359
+ * We expect `prefix` to be NUL terminated, therefore this
360
+ * `strcspn()` call is okay, even if it might do much more
361
+ * work than strictly necessary.
362
+ */
363
+ strcspn (prefix , " \t\r\n," ) >= prefix_len && /* separators */
364
+ * prefix != '-' && /* deselection */
365
+ !isdigit (* prefix ) && /* selection */
366
+ (prefix_len != 1 ||
367
+ (* prefix != '*' && /* "all" wildcard */
368
+ * prefix != '?' )); /* prompt help */
369
+ }
370
+
334
371
struct print_file_item_data {
335
372
const char * modified_fmt ;
336
373
struct strbuf buf , index , worktree ;
337
374
};
338
375
339
- static void print_file_item (int i , struct item * item ,
376
+ static void print_file_item (int i , struct prefix_item * item ,
340
377
void * print_file_item_data )
341
378
{
342
379
struct file_item * c = (struct file_item * )item ;
@@ -363,20 +400,26 @@ static int run_status(struct add_i_state *s, const struct pathspec *ps,
363
400
return -1 ;
364
401
365
402
if (files -> nr )
366
- list ((struct item * * )files -> file , files -> nr , s , opts );
403
+ list ((struct prefix_item * * )files -> file , files -> nr , s , opts );
367
404
putchar ('\n' );
368
405
369
406
return 0 ;
370
407
}
371
408
372
- static void print_command_item (int i , struct item * item ,
409
+ static void print_command_item (int i , struct prefix_item * item ,
373
410
void * print_command_item_data )
374
411
{
375
- printf (" %2d: %s" , i + 1 , item -> name );
412
+ if (!item -> prefix_length ||
413
+ !is_valid_prefix (item -> name , item -> prefix_length ))
414
+ printf (" %2d: %s" , i + 1 , item -> name );
415
+ else
416
+ printf (" %3d: [%.*s]%s" , i + 1 ,
417
+ (int )item -> prefix_length , item -> name ,
418
+ item -> name + item -> prefix_length );
376
419
}
377
420
378
421
struct command_item {
379
- struct item item ;
422
+ struct prefix_item item ;
380
423
int (* command )(struct add_i_state * s , const struct pathspec * ps ,
381
424
struct file_list * files , struct list_options * opts );
382
425
};
@@ -418,7 +461,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
418
461
res = -1 ;
419
462
420
463
for (;;) {
421
- i = list_and_choose ((struct item * * )commands ,
464
+ i = list_and_choose ((struct prefix_item * * )commands ,
422
465
ARRAY_SIZE (commands ), & s , & main_loop_opts );
423
466
if (i < -1 ) {
424
467
printf (_ ("Bye.\n" ));
0 commit comments