[PATCH 4/4] allow recovery from command name typos

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If suggestions are available (based on Levenshtein distance) and if the
terminal isatty(), present a prompt to the user to select one of the
computed suggestions.

In the case where there is a single suggestion, present the prompt
"[Y/n]", such that "", "y" and "Y" as input leads git to proceed
executing the suggestion, while everything else (possibly "n") leads git
to terminate.

In the case where there are multiple suggestions, number the suggestions
1 to n, and accept as input one of the numbers, while everything else
(possibly "n") leads git to terminate. In this case there is no default;
that is, an empty input leads git to terminate. A sample run:

  $ git sh --pretty=oneline
  git: 'sh' is not a git command. See 'git --help'.

  Did you mean one of these?
  1:	show
  2:	push
  [1/2/.../n] 1

Signed-off-by: Tay Ray Chuan <rctay89@xxxxxxxxx>
---
 help.c | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/help.c b/help.c
index f296d95..4aa1d88 100644
--- a/help.c
+++ b/help.c
@@ -6,6 +6,7 @@
 #include "common-cmds.h"
 #include "string-list.h"
 #include "column.h"
+#include "compat/terminal.h"
 
 void add_cmdname(struct cmdnames *cmds, const char *name, int len)
 {
@@ -383,8 +384,40 @@ const char *help_unknown_cmd(const char *cmd)
 			      "\nDid you mean one of these?",
 			   n));
 
-		for (i = 0; i < n; i++)
-			fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
+		if (!isatty(2))
+			for (i = 0; i < n; i++)
+				fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
+		else if (n == 1) {
+			char *in;
+			const char *ret;
+			fprintf(stderr, "\t%s\n", main_cmds.names[0]->name);
+			in = git_terminal_prompt("[Y/n] ", 1);
+			switch (in[0]) {
+			case 'y': case 'Y': case 0:
+				ret = xstrdup(main_cmds.names[0]->name);
+				clean_cmdnames(&main_cmds);
+				return ret;
+			/* otherwise, don't do anything */
+			}
+		} else {
+			char *in;
+			const char *ret;
+			int opt;
+			for (i = 0; i < n; i++)
+				fprintf(stderr, "%d:\t%s\n", i + 1, main_cmds.names[i]->name);
+			in = git_terminal_prompt("[1/2/.../n] ", 1);
+			switch (in[0]) {
+				case 'n': case 'N': case 0:
+					;
+				default:
+					opt = atoi(in);
+					if (0 < opt && opt <= n) {
+						ret = xstrdup(main_cmds.names[opt - 1]->name);
+						clean_cmdnames(&main_cmds);
+						return ret;
+					}
+			}
+		}
 	}
 
 	exit(1);
-- 
1.7.10.1.611.g8a79d96

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]