changeset 24222:02d7b5cd373b

dispatch: offer suggestions of similar-named commands When suggestions are available, we show those suggestions instead of showing some help output.
author Augie Fackler <augie@google.com>
date Tue, 10 Feb 2015 15:59:12 -0500
parents 4e240d6ab898
children b4df0d0c49e7
files mercurial/cmdutil.py mercurial/commands.py mercurial/dispatch.py tests/test-alias.t tests/test-revset.t
diffstat 5 files changed, 29 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/cmdutil.py	Mon Jan 26 15:43:13 2015 -0500
+++ b/mercurial/cmdutil.py	Tue Feb 10 15:59:12 2015 -0500
@@ -34,8 +34,10 @@
     else:
         keys = table.keys()
 
+    allcmds = []
     for e in keys:
         aliases = parsealiases(e)
+        allcmds.extend(aliases)
         found = None
         if cmd in aliases:
             found = cmd
@@ -53,11 +55,11 @@
     if not choice and debugchoice:
         choice = debugchoice
 
-    return choice
+    return choice, allcmds
 
 def findcmd(cmd, table, strict=True):
     """Return (aliases, command table entry) for command string."""
-    choice = findpossible(cmd, table, strict)
+    choice, allcmds = findpossible(cmd, table, strict)
 
     if cmd in choice:
         return choice[cmd]
@@ -70,7 +72,7 @@
     if choice:
         return choice.values()[0]
 
-    raise error.UnknownCommand(cmd)
+    raise error.UnknownCommand(cmd, allcmds)
 
 def findrepo(p):
     while not os.path.isdir(os.path.join(p, ".hg")):
--- a/mercurial/commands.py	Mon Jan 26 15:43:13 2015 -0500
+++ b/mercurial/commands.py	Tue Feb 10 15:59:12 2015 -0500
@@ -1946,7 +1946,7 @@
         ui.write("%s\n" % "\n".join(options))
         return
 
-    cmdlist = cmdutil.findpossible(cmd, table)
+    cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
     if ui.verbose:
         cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
     ui.write("%s\n" % "\n".join(sorted(cmdlist)))
--- a/mercurial/dispatch.py	Mon Jan 26 15:43:13 2015 -0500
+++ b/mercurial/dispatch.py	Tue Feb 10 15:59:12 2015 -0500
@@ -220,7 +220,15 @@
             # (but don't check for extensions themselves)
             commands.help_(ui, inst.args[0], unknowncmd=True)
         except error.UnknownCommand:
-            commands.help_(ui, 'shortlist')
+            suggested = False
+            if len(inst.args) == 2:
+                sim = _getsimilar(inst.args[1], inst.args[0])
+                if sim:
+                    ui.warn(_('(did you mean one of %s?)\n') %
+                            ', '.join(sorted(sim)))
+                    suggested = True
+            if not suggested:
+                commands.help_(ui, 'shortlist')
     except error.InterventionRequired, inst:
         ui.warn("%s\n" % inst)
         return 1
--- a/tests/test-alias.t	Mon Jan 26 15:43:13 2015 -0500
+++ b/tests/test-alias.t	Tue Feb 10 15:59:12 2015 -0500
@@ -360,9 +360,11 @@
   sub
   $ hg --cwd .. subalias > /dev/null
   hg: unknown command 'subalias'
+  (did you mean one of idalias?)
   [255]
   $ hg -R .. subalias > /dev/null
   hg: unknown command 'subalias'
+  (did you mean one of idalias?)
   [255]
 
 
@@ -370,12 +372,18 @@
 
   $ hg mainalias > /dev/null
   hg: unknown command 'mainalias'
+  (did you mean one of idalias?)
   [255]
   $ hg -R .. mainalias
   main
   $ hg --cwd .. mainalias
   main
 
+typos get useful suggestions
+  $ hg --cwd .. manalias
+  hg: unknown command 'manalias'
+  (did you mean one of idalias, mainalias, manifest?)
+  [255]
 
 shell aliases with escaped $ chars
 
--- a/tests/test-revset.t	Mon Jan 26 15:43:13 2015 -0500
+++ b/tests/test-revset.t	Tue Feb 10 15:59:12 2015 -0500
@@ -890,19 +890,19 @@
 
 Bogus function gets suggestions
   $ log 'add()'
-  hg: parse error: not a function: add
+  hg: parse error: unknown identifier: add
   (did you mean 'adds'?)
   [255]
   $ log 'added()'
-  hg: parse error: not a function: added
+  hg: parse error: unknown identifier: added
   (did you mean 'adds'?)
   [255]
   $ log 'remo()'
-  hg: parse error: not a function: remo
+  hg: parse error: unknown identifier: remo
   (did you mean one of remote, removes?)
   [255]
   $ log 'babar()'
-  hg: parse error: not a function: babar
+  hg: parse error: unknown identifier: babar
   [255]
 
 multiple revspecs
@@ -1056,12 +1056,12 @@
     (range
       ('symbol', '2')
       ('symbol', '5')))
-  abort: failed to parse the definition of revset alias "injectparamasstring2": not a function: _aliasarg
+  abort: failed to parse the definition of revset alias "injectparamasstring2": unknown identifier: _aliasarg
   [255]
   $ hg debugrevspec --debug --config revsetalias.anotherbadone='branch(' "tip"
   ('symbol', 'tip')
   warning: failed to parse the definition of revset alias "anotherbadone": at 7: not a prefix: end
-  warning: failed to parse the definition of revset alias "injectparamasstring2": not a function: _aliasarg
+  warning: failed to parse the definition of revset alias "injectparamasstring2": unknown identifier: _aliasarg
   9
   >>> data = file('.hg/hgrc', 'rb').read()
   >>> file('.hg/hgrc', 'wb').write(data.replace('_aliasarg', ''))