Merge branch 'ef/help-cmd-prefix'
* ef/help-cmd-prefix: help: always suggest common-cmds if prefix of cmd
This commit is contained in:
commit
4a29c6a0db
2
Makefile
2
Makefile
@ -1675,6 +1675,8 @@ git$X: git.o $(BUILTIN_OBJS) $(GITLIBS)
|
|||||||
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \
|
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \
|
||||||
$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
|
$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
|
||||||
|
|
||||||
|
help.o: common-cmds.h
|
||||||
|
|
||||||
builtin/help.o: common-cmds.h
|
builtin/help.o: common-cmds.h
|
||||||
builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \
|
builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \
|
||||||
'-DGIT_HTML_PATH="$(htmldir_SQ)"' \
|
'-DGIT_HTML_PATH="$(htmldir_SQ)"' \
|
||||||
|
47
help.c
47
help.c
@ -3,6 +3,7 @@
|
|||||||
#include "exec_cmd.h"
|
#include "exec_cmd.h"
|
||||||
#include "levenshtein.h"
|
#include "levenshtein.h"
|
||||||
#include "help.h"
|
#include "help.h"
|
||||||
|
#include "common-cmds.h"
|
||||||
|
|
||||||
/* most GUI terminals set COLUMNS (although some don't export it) */
|
/* most GUI terminals set COLUMNS (although some don't export it) */
|
||||||
static int term_columns(void)
|
static int term_columns(void)
|
||||||
@ -298,7 +299,8 @@ static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* An empirically derived magic number */
|
/* An empirically derived magic number */
|
||||||
#define SIMILAR_ENOUGH(x) ((x) < 6)
|
#define SIMILARITY_FLOOR 7
|
||||||
|
#define SIMILAR_ENOUGH(x) ((x) < SIMILARITY_FLOOR)
|
||||||
|
|
||||||
const char *help_unknown_cmd(const char *cmd)
|
const char *help_unknown_cmd(const char *cmd)
|
||||||
{
|
{
|
||||||
@ -319,10 +321,28 @@ const char *help_unknown_cmd(const char *cmd)
|
|||||||
sizeof(main_cmds.names), cmdname_compare);
|
sizeof(main_cmds.names), cmdname_compare);
|
||||||
uniq(&main_cmds);
|
uniq(&main_cmds);
|
||||||
|
|
||||||
/* This reuses cmdname->len for similarity index */
|
/* This abuses cmdname->len for levenshtein distance */
|
||||||
for (i = 0; i < main_cmds.cnt; ++i)
|
for (i = 0, n = 0; i < main_cmds.cnt; i++) {
|
||||||
|
int cmp = 0; /* avoid compiler stupidity */
|
||||||
|
const char *candidate = main_cmds.names[i]->name;
|
||||||
|
|
||||||
|
/* Does the candidate appear in common_cmds list? */
|
||||||
|
while (n < ARRAY_SIZE(common_cmds) &&
|
||||||
|
(cmp = strcmp(common_cmds[n].name, candidate)) < 0)
|
||||||
|
n++;
|
||||||
|
if ((n < ARRAY_SIZE(common_cmds)) && !cmp) {
|
||||||
|
/* Yes, this is one of the common commands */
|
||||||
|
n++; /* use the entry from common_cmds[] */
|
||||||
|
if (!prefixcmp(candidate, cmd)) {
|
||||||
|
/* Give prefix match a very good score */
|
||||||
|
main_cmds.names[i]->len = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
main_cmds.names[i]->len =
|
main_cmds.names[i]->len =
|
||||||
levenshtein(cmd, main_cmds.names[i]->name, 0, 2, 1, 4);
|
levenshtein(cmd, candidate, 0, 2, 1, 4) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
qsort(main_cmds.names, main_cmds.cnt,
|
qsort(main_cmds.names, main_cmds.cnt,
|
||||||
sizeof(*main_cmds.names), levenshtein_compare);
|
sizeof(*main_cmds.names), levenshtein_compare);
|
||||||
@ -330,10 +350,21 @@ const char *help_unknown_cmd(const char *cmd)
|
|||||||
if (!main_cmds.cnt)
|
if (!main_cmds.cnt)
|
||||||
die ("Uh oh. Your system reports no Git commands at all.");
|
die ("Uh oh. Your system reports no Git commands at all.");
|
||||||
|
|
||||||
best_similarity = main_cmds.names[0]->len;
|
/* skip and count prefix matches */
|
||||||
n = 1;
|
for (n = 0; n < main_cmds.cnt && !main_cmds.names[n]->len; n++)
|
||||||
while (n < main_cmds.cnt && best_similarity == main_cmds.names[n]->len)
|
; /* still counting */
|
||||||
++n;
|
|
||||||
|
if (main_cmds.cnt <= n) {
|
||||||
|
/* prefix matches with everything? that is too ambiguous */
|
||||||
|
best_similarity = SIMILARITY_FLOOR + 1;
|
||||||
|
} else {
|
||||||
|
/* count all the most similar ones */
|
||||||
|
for (best_similarity = main_cmds.names[n++]->len;
|
||||||
|
(n < main_cmds.cnt &&
|
||||||
|
best_similarity == main_cmds.names[n]->len);
|
||||||
|
n++)
|
||||||
|
; /* still counting */
|
||||||
|
}
|
||||||
if (autocorrect && n == 1 && SIMILAR_ENOUGH(best_similarity)) {
|
if (autocorrect && n == 1 && SIMILAR_ENOUGH(best_similarity)) {
|
||||||
const char *assumed = main_cmds.names[0]->name;
|
const char *assumed = main_cmds.names[0]->name;
|
||||||
main_cmds.names[0] = NULL;
|
main_cmds.names[0] = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user