5
5
#include "run-command.h"
6
6
#include "levenshtein.h"
7
7
#include "help.h"
8
- #include "common-cmds .h"
8
+ #include "command-list .h"
9
9
#include "string-list.h"
10
10
#include "column.h"
11
11
#include "version.h"
12
12
#include "refs.h"
13
13
#include "parse-options.h"
14
14
15
+ struct category_description {
16
+ uint32_t category ;
17
+ const char * desc ;
18
+ };
19
+ static uint32_t common_mask =
20
+ CAT_init | CAT_worktree | CAT_info |
21
+ CAT_history | CAT_remote ;
22
+ static struct category_description common_categories [] = {
23
+ { CAT_init , N_ ("start a working area (see also: git help tutorial)" ) },
24
+ { CAT_worktree , N_ ("work on the current change (see also: git help everyday)" ) },
25
+ { CAT_info , N_ ("examine the history and state (see also: git help revisions)" ) },
26
+ { CAT_history , N_ ("grow, mark and tweak your common history" ) },
27
+ { CAT_remote , N_ ("collaborate (see also: git help workflows)" ) },
28
+ { 0 , NULL }
29
+ };
30
+
31
+ static const char * drop_prefix (const char * name )
32
+ {
33
+ const char * new_name ;
34
+
35
+ if (skip_prefix (name , "git-" , & new_name ))
36
+ return new_name ;
37
+ return name ;
38
+
39
+ }
40
+
41
+ static void extract_cmds (struct cmdname_help * * p_cmds , uint32_t mask )
42
+ {
43
+ int i , nr = 0 ;
44
+ struct cmdname_help * cmds ;
45
+
46
+ if (ARRAY_SIZE (command_list ) == 0 )
47
+ BUG ("empty command_list[] is a sign of broken generate-cmdlist.sh" );
48
+
49
+ ALLOC_ARRAY (cmds , ARRAY_SIZE (command_list ) + 1 );
50
+
51
+ for (i = 0 ; i < ARRAY_SIZE (command_list ); i ++ ) {
52
+ const struct cmdname_help * cmd = command_list + i ;
53
+
54
+ if (!(cmd -> category & mask ))
55
+ continue ;
56
+
57
+ cmds [nr ] = * cmd ;
58
+ cmds [nr ].name = drop_prefix (cmd -> name );
59
+
60
+ nr ++ ;
61
+ }
62
+ cmds [nr ].name = NULL ;
63
+ * p_cmds = cmds ;
64
+ }
65
+
66
+ static void print_command_list (const struct cmdname_help * cmds ,
67
+ uint32_t mask , int longest )
68
+ {
69
+ int i ;
70
+
71
+ for (i = 0 ; cmds [i ].name ; i ++ ) {
72
+ if (cmds [i ].category & mask ) {
73
+ printf (" %s " , cmds [i ].name );
74
+ mput_char (' ' , longest - strlen (cmds [i ].name ));
75
+ puts (_ (cmds [i ].help ));
76
+ }
77
+ }
78
+ }
79
+
80
+ static int cmd_name_cmp (const void * elem1 , const void * elem2 )
81
+ {
82
+ const struct cmdname_help * e1 = elem1 ;
83
+ const struct cmdname_help * e2 = elem2 ;
84
+
85
+ return strcmp (e1 -> name , e2 -> name );
86
+ }
87
+
88
+ static void print_cmd_by_category (const struct category_description * catdesc )
89
+ {
90
+ struct cmdname_help * cmds ;
91
+ int longest = 0 ;
92
+ int i , nr = 0 ;
93
+ uint32_t mask = 0 ;
94
+
95
+ for (i = 0 ; catdesc [i ].desc ; i ++ )
96
+ mask |= catdesc [i ].category ;
97
+
98
+ extract_cmds (& cmds , mask );
99
+
100
+ for (i = 0 ; cmds [i ].name ; i ++ , nr ++ ) {
101
+ if (longest < strlen (cmds [i ].name ))
102
+ longest = strlen (cmds [i ].name );
103
+ }
104
+ QSORT (cmds , nr , cmd_name_cmp );
105
+
106
+ for (i = 0 ; catdesc [i ].desc ; i ++ ) {
107
+ uint32_t mask = catdesc [i ].category ;
108
+ const char * desc = catdesc [i ].desc ;
109
+
110
+ printf ("\n%s\n" , _ (desc ));
111
+ print_command_list (cmds , mask , longest );
112
+ }
113
+ free (cmds );
114
+ }
115
+
15
116
void add_cmdname (struct cmdnames * cmds , const char * name , int len )
16
117
{
17
118
struct cmdname * ent ;
@@ -190,42 +291,10 @@ void list_commands(unsigned int colopts,
190
291
}
191
292
}
192
293
193
- static int cmd_group_cmp (const void * elem1 , const void * elem2 )
194
- {
195
- const struct cmdname_help * e1 = elem1 ;
196
- const struct cmdname_help * e2 = elem2 ;
197
-
198
- if (e1 -> group < e2 -> group )
199
- return -1 ;
200
- if (e1 -> group > e2 -> group )
201
- return 1 ;
202
- return strcmp (e1 -> name , e2 -> name );
203
- }
204
-
205
294
void list_common_cmds_help (void )
206
295
{
207
- int i , longest = 0 ;
208
- int current_grp = -1 ;
209
-
210
- for (i = 0 ; i < ARRAY_SIZE (common_cmds ); i ++ ) {
211
- if (longest < strlen (common_cmds [i ].name ))
212
- longest = strlen (common_cmds [i ].name );
213
- }
214
-
215
- QSORT (common_cmds , ARRAY_SIZE (common_cmds ), cmd_group_cmp );
216
-
217
296
puts (_ ("These are common Git commands used in various situations:" ));
218
-
219
- for (i = 0 ; i < ARRAY_SIZE (common_cmds ); i ++ ) {
220
- if (common_cmds [i ].group != current_grp ) {
221
- printf ("\n%s\n" , _ (common_cmd_groups [common_cmds [i ].group ]));
222
- current_grp = common_cmds [i ].group ;
223
- }
224
-
225
- printf (" %s " , common_cmds [i ].name );
226
- mput_char (' ' , longest - strlen (common_cmds [i ].name ));
227
- puts (_ (common_cmds [i ].help ));
228
- }
297
+ print_cmd_by_category (common_categories );
229
298
}
230
299
231
300
int is_in_cmdlist (struct cmdnames * c , const char * s )
@@ -285,6 +354,7 @@ const char *help_unknown_cmd(const char *cmd)
285
354
{
286
355
int i , n , best_similarity = 0 ;
287
356
struct cmdnames main_cmds , other_cmds ;
357
+ struct cmdname_help * common_cmds ;
288
358
289
359
memset (& main_cmds , 0 , sizeof (main_cmds ));
290
360
memset (& other_cmds , 0 , sizeof (other_cmds ));
@@ -299,6 +369,8 @@ const char *help_unknown_cmd(const char *cmd)
299
369
QSORT (main_cmds .names , main_cmds .cnt , cmdname_compare );
300
370
uniq (& main_cmds );
301
371
372
+ extract_cmds (& common_cmds , common_mask );
373
+
302
374
/* This abuses cmdname->len for levenshtein distance */
303
375
for (i = 0 , n = 0 ; i < main_cmds .cnt ; i ++ ) {
304
376
int cmp = 0 ; /* avoid compiler stupidity */
@@ -313,10 +385,10 @@ const char *help_unknown_cmd(const char *cmd)
313
385
die (_ (bad_interpreter_advice ), cmd , cmd );
314
386
315
387
/* Does the candidate appear in common_cmds list? */
316
- while (n < ARRAY_SIZE ( common_cmds ) &&
388
+ while (common_cmds [ n ]. name &&
317
389
(cmp = strcmp (common_cmds [n ].name , candidate )) < 0 )
318
390
n ++ ;
319
- if (( n < ARRAY_SIZE ( common_cmds )) && !cmp ) {
391
+ if (common_cmds [ n ]. name && !cmp ) {
320
392
/* Yes, this is one of the common commands */
321
393
n ++ ; /* use the entry from common_cmds[] */
322
394
if (starts_with (candidate , cmd )) {
@@ -329,6 +401,7 @@ const char *help_unknown_cmd(const char *cmd)
329
401
main_cmds .names [i ]-> len =
330
402
levenshtein (cmd , candidate , 0 , 2 , 1 , 3 ) + 1 ;
331
403
}
404
+ FREE_AND_NULL (common_cmds );
332
405
333
406
QSORT (main_cmds .names , main_cmds .cnt , levenshtein_compare );
334
407
0 commit comments