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', ''))