[PATCH 6 of 6 sethelp v2] dispatch: offer suggestions of similar-named commands

Augie Fackler raf at durin42.com
Fri Mar 6 17:01:47 CST 2015


# HG changeset patch
# User Augie Fackler <augie at google.com>
# Date 1423601952 18000
#      Tue Feb 10 15:59:12 2015 -0500
# Node ID 64f07db33efdff4c69f0df53fb061c049525c861
# Parent  ad097fb4dac7451651fcf631b930dcabc6d3481e
dispatch: offer suggestions of similar-named commands

When suggestions are available, we show those suggestions instead of
showing some help output.

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -34,8 +34,10 @@ def findpossible(cmd, table, strict=Fals
     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 @@ def findpossible(cmd, table, strict=Fals
     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 @@ def findcmd(cmd, table, strict=True):
     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")):
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -1946,7 +1946,7 @@ def debugcomplete(ui, cmd='', **opts):
         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)))
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -220,7 +220,15 @@ def _runcatch(req):
             # (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
diff --git a/tests/test-alias.t b/tests/test-alias.t
--- a/tests/test-alias.t
+++ b/tests/test-alias.t
@@ -360,9 +360,11 @@ shell alias defined in current repo
   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 @@ shell alias defined in other repo
 
   $ 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
 
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -890,19 +890,19 @@ parentrevspec
 
 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 @@ far away.
     (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', ''))


More information about the Mercurial-devel mailing list