提交 4a29c6a0 编写于 作者: J Junio C Hamano

Merge branch 'ef/help-cmd-prefix'

* ef/help-cmd-prefix:
  help: always suggest common-cmds if prefix of cmd
......@@ -1675,6 +1675,8 @@ git$X: git.o $(BUILTIN_OBJS) $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \
$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
help.o: common-cmds.h
builtin/help.o: common-cmds.h
builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \
'-DGIT_HTML_PATH="$(htmldir_SQ)"' \
......
......@@ -3,6 +3,7 @@
#include "exec_cmd.h"
#include "levenshtein.h"
#include "help.h"
#include "common-cmds.h"
/* most GUI terminals set COLUMNS (although some don't export it) */
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 */
#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)
{
......@@ -319,10 +321,28 @@ const char *help_unknown_cmd(const char *cmd)
sizeof(main_cmds.names), cmdname_compare);
uniq(&main_cmds);
/* This reuses cmdname->len for similarity index */
for (i = 0; i < main_cmds.cnt; ++i)
/* This abuses cmdname->len for levenshtein distance */
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 =
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,
sizeof(*main_cmds.names), levenshtein_compare);
......@@ -330,10 +350,21 @@ const char *help_unknown_cmd(const char *cmd)
if (!main_cmds.cnt)
die ("Uh oh. Your system reports no Git commands at all.");
best_similarity = main_cmds.names[0]->len;
n = 1;
while (n < main_cmds.cnt && best_similarity == main_cmds.names[n]->len)
++n;
/* skip and count prefix matches */
for (n = 0; n < main_cmds.cnt && !main_cmds.names[n]->len; n++)
; /* still counting */
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)) {
const char *assumed = main_cmds.names[0]->name;
main_cmds.names[0] = NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册